diff --git a/boards.txt b/boards.txt index c53e13e0..4cab8d6c 100644 --- a/boards.txt +++ b/boards.txt @@ -1,26 +1,29 @@ -# See: http://code.google.com/p/arduino/wiki/Platforms - -menu.cpu=Processor -############################################################## -izmir_ec.name=Intel® AtlasEdge -izmir_ec.upload.tool=shakespere -izmir_ec.upload.protocol=shakespere -izmir_ec.upload.maximum_size=10000000 -izmir_ec.upload.use_1200bps_touch=false -izmir_ec.upload.wait_for_upload_port=false -izmir_ec.upload.native_usb=false - -izmir_ec.build.mcu=arc32 -izmir_ec.build.f_cpu=-m32 -#izmir_ec.build.main=arduino\main.cpp -izmir_ec.build.core=arduino -izmir_ec.build.variant=atlas_fab_c -#izmir_ec.build.variant_system_lib=libx86_izmir_gcc_rel.a -izmir_ec.build.toolchain_path=x86_64-pokysdk-linux-eglibc/usr/bin/i586-poky-linux -izmir_ec.build.sysroot_path=i586-poky-linux-eglibc -izmir_ec.build.toolchain_prefix=i586-poky-linux- +intel_edu_x.name=Intel® EDU +intel_edu_x.vid.0=0x2341 +intel_edu_x.pid.0=0x003e +intel_edu_x.vid.1=0x2A03 +intel_edu_x.pid.1=0x003e +intel_edu_x.vid.0x2A03.warning=Uncertified +intel_edu_x.upload.tool=eduload +intel_edu_x.upload.protocol=script +intel_edu_x.upload.maximum_size=196608 +intel_edu_x.upload.use_1200bps_touch=falase +intel_edu_x.upload.wait_for_upload_port=false +intel_edu_x.upload.native_usb=false +intel_edu_x.upload.params.quiet=-q +intel_edu_x.upload.params.verbose=-q +intel_edu_x.build.usb_product="Arduino Due" +intel_edu_x.build.mcu=ARCv2EM +intel_edu_x.build.board=ARC32_TOOLS +intel_edu_x.build.core=arduino +intel_edu_x.build.ldscript=linker_scripts/flash.ld +intel_edu_x.build.variant=intel_edu_x +intel_edu_x.build.variant_system_lib=arc32drv_edu +intel_edu_x.build.vid=0x2341 +intel_edu_x.build.pid=0x003e +# See: http://code.google.com/p/arduino/wiki/Platforms diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 7bd1442e..2d0a177a 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -19,7 +19,92 @@ #ifndef Arduino_h #define Arduino_h -void setup(void); -void loop(void); -/*int main(void);*/ + +#include +#include +#include +#include + +#include "binary.h" +#include "itoa.h" + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#include "wiring_constants.h" + +#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L ) +#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) ) +#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) ) + +void yield(void); + +/* sketch */ +extern void setup( void ) ; +extern void loop( void ) ; + +typedef void (*voidFuncPtr)( void ) ; + +/* Define attribute */ +#define WEAK __attribute__ ((weak)) + +#define INVALID 0xFFFFFFFF + +/* Types used for the tables below */ +/* TODO - consider using smaller types to optimise storage space */ +typedef struct _PinDescription +{ + uint32_t ulGPIOId; // GPIO port pin + uint32_t ulGPIOPort; // GPIO port ID + uint32_t ulGPIOType; // LMT or SS + uint32_t ulGPIOBase; // GPIO register base address + uint32_t ulSocPin; // SoC pin number + uint32_t ulPinMode; // Current SoC pin mux mode + uint32_t ulPwmChan; // PWM channel + uint32_t ulPwmScale; // PWM frequency scaler +} PinDescription; + +#ifdef OUT +/* Types used for the tables below */ +typedef struct _PinDescription +{ + // TODO Pio* pPort ; + uint32_t ulPin ; + uint32_t ulPeripheralId ; + // TODO EPioType ulPinType ; + uint32_t ulPinConfiguration ; + uint32_t ulPinAttribute ; + EAnalogChannel ulAnalogChannel ; /* Analog pin in the Arduino context (label on the board) */ + EAnalogChannel ulADCChannelNumber ; /* ADC Channel number in the SAM device */ + EPWMChannel ulPWMChannel ; + ETCChannel ulTCChannel ; +} PinDescription ; #endif + + +/* Pins table to be instanciated into variant.cpp */ +extern PinDescription g_APinDescription[] ; + +#ifdef __cplusplus +} // extern "C" + +#include "WCharacter.h" +#include "WString.h" +#include "Tone.h" +#include "WMath.h" +#include "HardwareSerial.h" +#include "wiring_pulse.h" + +#endif // __cplusplus + +// Include board variant +#include "variant.h" + +#include "wiring.h" +#include "wiring_digital.h" +#include "wiring_analog.h" +#include "wiring_shift.h" +#include "WInterrupts.h" + +#endif // Arduino_h diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h new file mode 100644 index 00000000..5674e57a --- /dev/null +++ b/cores/arduino/HardwareSerial.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include + +#include "Stream.h" + +class HardwareSerial : public Stream +{ + public: + virtual void begin(unsigned long); + virtual void end(); + virtual int available(void) = 0; + virtual int peek(void) = 0; + virtual int read(void) = 0; + virtual void flush(void) = 0; + virtual size_t write(uint8_t) = 0; + using Print::write; // pull in write(str) and write(buf, size) from Print + virtual operator bool() = 0; +}; + +extern void serialEventRun(void) __attribute__((weak)); + +#endif diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h new file mode 100644 index 00000000..7b53aa4d --- /dev/null +++ b/cores/arduino/Print.h @@ -0,0 +1,84 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); +}; + +#endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h new file mode 100644 index 00000000..2a1b2e9f --- /dev/null +++ b/cores/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h new file mode 100644 index 00000000..0d9a49ac --- /dev/null +++ b/cores/arduino/Stream.h @@ -0,0 +1,112 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(char skipChar); // as above but the given skipChar is ignored + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#endif diff --git a/cores/arduino/Tone.h b/cores/arduino/Tone.h new file mode 100644 index 00000000..5789b082 --- /dev/null +++ b/cores/arduino/Tone.h @@ -0,0 +1,23 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_TONE_ +#define _WIRING_TONE_ + + +#endif /* _WIRING_TONE_ */ diff --git a/cores/arduino/WCharacter.h b/cores/arduino/WCharacter.h new file mode 100644 index 00000000..e84b3485 --- /dev/null +++ b/cores/arduino/WCharacter.h @@ -0,0 +1,180 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// WCharacter.h prototypes +#if defined ( __GNUC__ ) +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); +#elif defined ( __ICCARM__ ) +#endif + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) +{ +/* return ( isascii(c) == 0 ? false : true); */ + return ( (c & ~0x7f) != 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ +/* return toascii (c); */ + return (c & 0x7f); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h new file mode 100644 index 00000000..bb698cdf --- /dev/null +++ b/cores/arduino/WInterrupts.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2011-2012 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_INTERRUPTS_ +#define _WIRING_INTERRUPTS_ + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode); + +void detachInterrupt(uint32_t pin); + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_INTERRUPTS_ */ diff --git a/cores/arduino/WMath.h b/cores/arduino/WMath.h new file mode 100644 index 00000000..05779eaf --- /dev/null +++ b/cores/arduino/WMath.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_MATH_ +#define _WIRING_MATH_ + +extern long random( long ) ; +extern long random( long, long ) ; +extern void randomSeed( uint32_t dwSeed ) ; +extern long map( long, long, long, long, long ) ; + +extern uint16_t makeWord( uint16_t w ) ; +extern uint16_t makeWord( uint8_t h, uint8_t l ) ; + +#define word(...) makeWord(__VA_ARGS__) + + +#endif /* _WIRING_MATH_ */ diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h new file mode 100644 index 00000000..5cbdc882 --- /dev/null +++ b/cores/arduino/WString.h @@ -0,0 +1,223 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/cores/arduino/binary.h b/cores/arduino/binary.h new file mode 100644 index 00000000..aec4c733 --- /dev/null +++ b/cores/arduino/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/cores/arduino/itoa.h b/cores/arduino/itoa.h new file mode 100644 index 00000000..59af1094 --- /dev/null +++ b/cores/arduino/itoa.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ITOA_ +#define _ITOA_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#if 0 + +extern void itoa( int n, char s[] ) ; + +#else + +extern char* itoa( int value, char *string, int radix ) ; +extern char* ltoa( long value, char *string, int radix ) ; +extern char* utoa( unsigned long value, char *string, int radix ) ; +extern char* ultoa( unsigned long value, char *string, int radix ) ; +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ITOA_ diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index d2717140..acb46cb4 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -1,5 +1,5 @@ /* -main.cpp userspace main loop for Intel Galileo family boards +main.cpp userspace main loop for Intel EDU family boards Copyright (C) 2014 Intel Corporation This library is free software; you can redistribute it and/or @@ -16,23 +16,38 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ +*/ // Arduino hooks -#include -#include - -/************************ Static *************************/ +#include "Arduino.h" +#include "arcv2_timer1.h" +// Weak empty variant initialization function. +// May be redefined by variant files. +void initVariant() __attribute__((weak)); +void initVariant() { } -/************************ Global *************************/ -int main(int argc, char * argv[]) +/* + * \brief Main entry point of Arduino application + */ +int main( void ) { - printf("!!!Hello ARC World!!!\n\r"); + //init(); + + initVariant(); + + // delay(1); + +#if defined(USBCON) + USBDevice.attach(); +#endif + setup(); - for (;;) { + + for (;;) + { loop(); //if (serialEventRun) serialEventRun(); } + return 0; } - diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h new file mode 100644 index 00000000..2535be0d --- /dev/null +++ b/cores/arduino/wiring.h @@ -0,0 +1,99 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + Copyright (c) 2013 by Paul Stoffregen (delayMicroseconds) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_ +#define _WIRING_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + */ +extern void initVariant( void ) ; +extern void init( void ) ; + +/** + * \brief Returns the number of milliseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 50 days. + * + * \return Number of milliseconds since the program started (uint32_t) + */ +extern uint32_t millis( void ) ; + +/** + * \brief Returns the number of microseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards + * (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is + * always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution + * of eight microseconds. + * + * \note There are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second. + */ +extern uint32_t micros( void ) ; + +/** + * \brief Pauses the program for the amount of time (in miliseconds) specified as parameter. + * (There are 1000 milliseconds in a second.) + * + * \param dwMs the number of milliseconds to pause (uint32_t) + */ +#if 0 +extern void delay( uint32_t dwMs ) ; + +#else + +#include "arcv2_timer1.h" + +static volatile boolean_t expired = true; + +static void timer1_user_isr(void) +{ + expired = true; +} + +static inline void delay(uint32_t) __attribute__((always_inline)); +static inline void delay(uint32_t msec){ + /* TODO */ + expired = false; + timer1_driver_init(timer1_user_isr, msec); + while(!expired); +} +#endif + +/** + * \brief Pauses the program for the amount of time (in microseconds) specified as parameter. + * + * \param dwUs the number of microseconds to pause (uint32_t) + */ +#ifdef OUT +static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused)); +static inline void delayMicroseconds(uint32_t usec){ + /* TODO */ +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_ */ diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c new file mode 100644 index 00000000..a176f2f7 --- /dev/null +++ b/cores/arduino/wiring_analog.c @@ -0,0 +1,93 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "Arduino.h" +#include "portable.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Standard Arduino PWM resolution */ +static int _writeResolution = 8; + +void analogResolution(int res) +{ + _writeResolution = res; +} + +static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) +{ + if (from == to) + return value; + if (from > to) + return value >> (from-to); + else + return value << (to-from); +} + +void analogWrite(uint8_t pin, int val) +{ + if (! digitalPinHasPWM(pin)) return; + + if (val <= 0) { + /* Use GPIO for 0% duty cycle (always off) */ + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); + } else if (val >= ((1 << _writeResolution) - 1)) { + /* Use GPIO for 100% duty cycle (always on) */ + pinMode(pin, OUTPUT); + digitalWrite(pin, HIGH); + } else { + /* PWM for everything in between */ + PinDescription *p = &g_APinDescription[pin]; + uint32_t hcnt = mapResolution(val, _writeResolution, PWM_RESOLUTION); + uint32_t lcnt = PWM_MAX_DUTY_CYCLE - hcnt; + uint32_t offset; + + /* For Arduino Uno compatibilty, we scale up frequency on certain pins */ + hcnt >>= p->ulPwmScale; + lcnt >>= p->ulPwmScale; + + /* Each count must be > 0 */ + if (hcnt < PWM_MIN_DUTY_CYCLE) + hcnt = PWM_MIN_DUTY_CYCLE; + if (lcnt < PWM_MIN_DUTY_CYCLE) + lcnt = PWM_MIN_DUTY_CYCLE; + + /* Set the high count period (duty cycle) */ + offset = ((p->ulPwmChan * QRK_PWM_N_LCNT2_LEN) + QRK_PWM_N_LOAD_COUNT2); + MMIO_REG_VAL(QRK_PWM_BASE_ADDR + offset) = hcnt; + + /* Set the low count period (duty cycle) */ + offset = ((p->ulPwmChan * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_LOAD_COUNT1); + MMIO_REG_VAL(QRK_PWM_BASE_ADDR + offset) = lcnt; + + if (p->ulPinMode != PWM_MUX_MODE) { + /* start the PWM output */ + offset = ((p->ulPwmChan * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_CONTROL); + SET_MMIO_MASK(QRK_PWM_BASE_ADDR + offset, QRK_PWM_CONTROL_ENABLE); + + /* Disable pull-up and set pin mux for PWM output */ + SET_PIN_PULLUP(p->ulSocPin, 0); + SET_PIN_MODE(p->ulSocPin, PWM_MUX_MODE); + p->ulPinMode = PWM_MUX_MODE; + } + } +} diff --git a/cores/arduino/wiring_analog.h b/cores/arduino/wiring_analog.h new file mode 100644 index 00000000..a7c64a15 --- /dev/null +++ b/cores/arduino/wiring_analog.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_ANALOG_ +#define _WIRING_ANALOG_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO - update analogReference and other ADC-related functions for Intel EDU */ + +/* + * \brief SAM3 products have only one reference for ADC + */ +typedef enum _eAnalogReference +{ + AR_DEFAULT, +} eAnalogReference ; + +/* + * \brief Configures the reference voltage used for analog input (i.e. the value used as the top of the input range). + * This function is kept only for compatibility with existing AVR based API. + * + * \param ulMmode Should be set to AR_DEFAULT. + */ +extern void analogReference( eAnalogReference ulMode ) ; + +/* + * \brief Writes an analog value (PWM wave) to a pin. + * + * \param pin + * \param val + */ +extern void analogWrite( uint8_t pin, int val ) ; + +/* + * \brief Reads the value from the specified analog pin. + * + * \param ulPin + * + * \return Read value from selected pin, if no error. + */ +extern uint32_t analogRead( uint32_t ulPin ) ; + +/* + * \brief Set the resolution of analogRead return values. Default is 10 bits (range from 0 to 1023). + * + * \param res + */ +extern void analogReadResolution(int res); + +/* + * \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255). + * + * \param res + */ +extern void analogWriteResolution(int res); + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_ANALOG_ */ diff --git a/cores/arduino/wiring_constants.h b/cores/arduino/wiring_constants.h new file mode 100644 index 00000000..f1e39e93 --- /dev/null +++ b/cores/arduino/wiring_constants.h @@ -0,0 +1,103 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_CONSTANTS_ +#define _WIRING_CONSTANTS_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define true 0x1 +#define false 0x0 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +enum BitOrder { + LSBFIRST = 0, + MSBFIRST = 1 +}; + +// LOW 0 +// HIGH 1 +#define CHANGE 2 +#define FALLING 3 +#define RISING 4 + +#define DEFAULT 1 +#define EXTERNAL 0 + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif // abs + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif // min + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif // max + +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() __enable_irq() +#define noInterrupts() __disable_irq() + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +typedef unsigned int word; + +#define bit(b) (1UL << (b)) + +//typedef bool boolean ; +typedef int boolean ; +typedef uint8_t byte ; + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* _WIRING_CONSTANTS_ */ diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c new file mode 100644 index 00000000..9def98f3 --- /dev/null +++ b/cores/arduino/wiring_digital.c @@ -0,0 +1,106 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "Arduino.h" +#include "portable.h" + +#ifdef __cplusplus + extern "C" { +#endif + +void pinMode( uint8_t pin, uint8_t mode ) +{ + PinDescription *p = &g_APinDescription[pin]; + + if (mode == OUTPUT) { + if (p->ulGPIOType == SS_GPIO) { + uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DDR; + SET_ARC_BIT(reg, p->ulGPIOId); + } + else if (p->ulGPIOType == SOC_GPIO) { + uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DDR; + SET_MMIO_BIT(reg, p->ulGPIOId); + } + } else { + if (p->ulGPIOType == SS_GPIO) { + uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DDR; + CLEAR_ARC_BIT(reg, p->ulGPIOId); + } + else if (p->ulGPIOType == SOC_GPIO) { + uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DDR; + CLEAR_MMIO_BIT(reg, p->ulGPIOId); + } + } + + /* Set SoC pin mux configuration */ + SET_PIN_PULLUP(p->ulSocPin, (mode == INPUT_PULLUP) ? 1 : 0); + if (p->ulPinMode != GPIO_MUX_MODE) { + SET_PIN_MODE(p->ulSocPin, GPIO_MUX_MODE); + p->ulPinMode = GPIO_MUX_MODE; + } +} + +void digitalWrite( uint8_t pin, uint8_t val ) +{ + PinDescription *p = &g_APinDescription[pin]; + + if (pin >= NUM_DIGITAL_PINS) return; + + if (p->ulGPIOType == SS_GPIO) + { + uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DR; + if (val) + SET_ARC_BIT(reg, p->ulGPIOId); + else + CLEAR_ARC_BIT(reg, p->ulGPIOId); + } + else if (p->ulGPIOType == SOC_GPIO) + { + uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DR; + if (val) + SET_MMIO_BIT(reg, p->ulGPIOId); + else + CLEAR_MMIO_BIT(reg, p->ulGPIOId); + } +} + +int digitalRead( uint8_t pin ) +{ + PinDescription *p = &g_APinDescription[pin]; + + if (pin >= NUM_DIGITAL_PINS) return LOW; + + if (p->ulGPIOType == SS_GPIO) + { + uint32_t reg = p->ulGPIOBase + SS_GPIO_EXT_PORTA; + if (READ_ARC_REG(reg) & (1 << p->ulGPIOId)) return HIGH; + } + else if (p->ulGPIOType == SOC_GPIO) + { + uint32_t reg = p->ulGPIOBase + SOC_GPIO_EXT_PORTA; + if (MMIO_REG_VAL(reg) & (1 << p->ulGPIOId)) return HIGH; + } + + return LOW; +} + +#ifdef __cplusplus +} +#endif + diff --git a/cores/arduino/wiring_digital.h b/cores/arduino/wiring_digital.h new file mode 100644 index 00000000..5658140c --- /dev/null +++ b/cores/arduino/wiring_digital.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_DIGITAL_ +#define _WIRING_DIGITAL_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details. + * + * \param pin The number of the pin whose mode you wish to set + * \param mode Either INPUT, INPUT_PULLUP or OUTPUT + */ +extern void pinMode( uint8_t pin, uint8_t mode ) ; + +/** + * \brief Write a HIGH or a LOW value to a digital pin. + * + * If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the + * corresponding value: 3.3V for HIGH, 0V (ground) for LOW. + * + * TODO - update the text below for Intel EDU + * + * If the pin is configured as an INPUT, writing a HIGH value with digitalWrite() will enable an internal + * 20K pullup resistor (see the tutorial on digital pins). Writing LOW will disable the pullup. The pullup + * resistor is enough to light an LED dimly, so if LEDs appear to work, but very dimly, this is a likely + * cause. The remedy is to set the pin to an output with the pinMode() function. + * + * \note Digital pin PIN_LED is harder to use as a digital input than the other digital pins because it has an LED + * and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up + * resistor, it will hang at around 1.7 V instead of the expected 5V because the onboard LED and series resistor + * pull the voltage level down, meaning it always returns LOW. If you must use pin PIN_LED as a digital input, use an + * external pull down resistor. + * + * \param pin the pin number + * \param val HIGH or LOW + */ +extern void digitalWrite( uint8_t pin, uint8_t val ) ; + +/** + * \brief Reads the value from a specified digital pin, either HIGH or LOW. + * + * \param pin The number of the digital pin you want to read (int) + * + * \return HIGH or LOW + */ +extern int digitalRead( uint8_t pin ) ; + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_DIGITAL_ */ diff --git a/cores/arduino/wiring_pulse.h b/cores/arduino/wiring_pulse.h new file mode 100644 index 00000000..f3289698 --- /dev/null +++ b/cores/arduino/wiring_pulse.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_PULSE_ +#define _WIRING_PULSE_ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * \brief Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. + */ +extern uint32_t pulseIn( uint32_t ulPin, uint32_t ulState, uint32_t ulTimeout = 1000000L ) ; + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_PULSE_ */ diff --git a/cores/arduino/wiring_shift.h b/cores/arduino/wiring_shift.h new file mode 100644 index 00000000..f33d8485 --- /dev/null +++ b/cores/arduino/wiring_shift.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_SHIFT_ +#define _WIRING_SHIFT_ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * \brief + */ +extern uint32_t shiftIn( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder ) ; + + +/* + * \brief + */ +extern void shiftOut( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal ) ; + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_SHIFT_ */ diff --git a/platform.txt b/platform.txt index f1b0730b..a28f58d7 100644 --- a/platform.txt +++ b/platform.txt @@ -1,81 +1,96 @@ -name=Arduino arc32 Boards -version=0.0.1 +# Intel EDU Core and platform. +# +# For more info: +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -# arc32 compile variables -# --------------------- +name=Intel Curie (32-bit) Boards +version=1.6.2 + +# SAM3 compile variables +# ---------------------- -compiler.toolchain.path={runtime.ide.path}/hardware/tools/arc32 -compiler.path={compiler.toolchain.path}/bin/ -#compiler.path.linux={compiler.toolchain.path}/sysroots/pokysdk/usr/bin/i586-poky-linux/ -#compiler.sysroot={compiler.toolchain.path}/core2-32-poky-linux -#compiler.sysroot.linux={compiler.toolchain.path}/sysroots/core2-32-poky-linux compiler.prefix=arc-elf32 -compiler.c.cmd={compiler.prefix}-gcc -compiler.c.flags=-Wall -c -compiler.c.elf.cmd={compiler.prefix}-g++ -compiler.c.elf.flags=-Os -compiler.S.flags= -compiler.cpp.cmd={compiler.prefix}-g++ -compiler.cpp.flags=-Wall -c -compiler.ar.cmd={compiler.prefix}-ar + +compiler.path={runtime.tools.arc-elf32.path}/bin/ +compiler.c.cmd=arc-elf32-gcc +compiler.c.flags=-c -mARCv2EM -mav2em -mlittle-endian -g -Os -Wall -fno-reorder-functions -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-defer-pop -Wno-unused-but-set-variable -Wno-main -ffreestanding -fno-stack-protector -mno-sdata -ffunction-sections -fdata-sections -MMD +compiler.c.elf.cmd=arc-elf32-gcc +compiler.c.elf.flags=-nostartfiles -nodefaultlibs -nostdlib -static -Wl,-X -Wl,-N -Wl,-mARCv2EM -Wl,-marcelf -Wl,--gc-sections +compiler.S.flags=-c -g -x assembler-with-cpp +#compiler.cpp.cmd=arc-elf32-g++ +compiler.cpp.cmd=arc-elf32-gcc +compiler.cpp.flags=-c -mARCv2EM -mav2em -mlittle-endian -g -Os -Wall -fno-reorder-functions -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-defer-pop -Wno-unused-but-set-variable -Wno-main -ffreestanding -fno-stack-protector -mno-sdata -ffunction-sections -fdata-sections -MMD +compiler.ar.cmd=arc-elf32-ar compiler.ar.flags=rcs -compiler.objcopy.cmd={compiler.prefix}-objcopy -#compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 -#compiler.elf2hex.flags=-O ihex -R .eeprom -#compiler.elf2hex.cmd={compiler.prefix}-objcopy -#compiler.ldflags= -compiler.size.cmd={compiler.prefix}-size -#compiler.strip.cmd={compiler.prefix}-strip -compiler.strip.cmd= +compiler.objcopy.cmd=arc-elf32-objcopy +compiler.objcopy.eep.flags=-O ihex +compiler.elf2hex.flags=-S -O binary -R .note -R .comment -R COMMON -R .eh_frame +compiler.elf2hex.cmd=arc-elf32-objcopy +compiler.ldflags= +compiler.size.cmd=arc-elf32-size +compiler.define=-DARDUINO= +compiler.strip.cmd={compiler.prefix}-strip + # this can be overriden in boards.txt build.extra_flags= -# X86 compile patterns -# -------------------- +# These can be overridden in platform.local.txt +compiler.c.extra_flags=-D__CPU_ARC__ -DCLOCK_SPEED=32 -DCONFIG_SOC_GPIO_32 "-I{build.system.path}/libarc32_edu/common" "-I{build.system.path}/libarc32_edu/drivers" "-I{build.system.path}/libarc32_edu/bootcode" +compiler.c.elf.extra_flags= +compiler.cpp.extra_flags=-D__CPU_ARC__ -DCLOCK_SPEED=32 -DCONFIG_SOC_GPIO_32 "-I{build.system.path}/libarc32_edu/common" "-I{build.system.path}/libarc32_edu/drivers" "-I{build.system.path}/libarc32_edu/bootcode" +compiler.ar.extra_flags= +compiler.elf2hex.extra_flags= + + +#compiler.libsam.c.flags="-I{build.system.path}/libsam" "-I{build.system.path}/CMSIS/CMSIS/Include/" "-I{build.system.path}/CMSIS/Device/ATMEL/" + +# USB Flags +# --------- +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' + +# Default usb manufacturer will be replaced at compile time using +# numeric vendor ID if available or by board's specific value. +build.usb_manufacturer="Unknown" + + +# Intel EDU compile patterns +# --------------------- ## Compile c files -#recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -march={build.mcu} {build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + ## Compile c++ files -#recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -march={build.mcu} {build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" -#recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" -#recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" "{source_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" ## Create archives -recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}" +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" ## Combine gc-sections, archives, and objects -#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -march={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm -lpthread -#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm -lpthread -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" "-L{build.variant.path}" -Wl,--whole-archive "-l{build.variant_system_lib}" -Wl,--no-whole-archive -Wl,--start-group "-l{build.variant_system_lib}" -lc -lm -lgcc {object_files} "{build.path}/{archive_file}" -## Create eeprom -#recipe.objcopy.eep.pattern="{compiler.path}{compiler.strip.cmd}" "{build.path}/{build.project_name}.elf" -recipe.objcopy.eep.pattern="ls" +## Create output (.bin file) +recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" -## Create hex -recipe.objcopy.hex.pattern= +## Create output (.elf file) +recipe.objcopy.eep.pattern="{compiler.path}{compiler.strip.cmd}" "{build.path}/{build.project_name}.elf" ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=Total\s+([0-9]+).* - -# X86 Uploader/Programmers tools +# Arc Uploader/Programmers tools # ------------------- -tools.izmirdl.cmd.path={runtime.ide.path}/hardware/intel/i686/tools/izmir/clupload_osx.sh -tools.izmirdl.cmd.path.linux="{runtime.ide.path}/hardware/intel/i686/tools/izmir/clupload_linux.sh" -tools.izmirdl.cmd.path.windows={runtime.ide.path}/hardware/tools/x86/bin/bash.exe -tools.izmirdl.cmd.script.windows={runtime.ide.path}/hardware/intel/i686/tools/izmir/clupload_win.sh -tools.izmirdl.cmd.bin.windows={runtime.ide.path}\hardware\tools\x86\bin - +tools.eduload.cmd.path={runtime.tools.sketchUploader-1.6.2+1.0.path}/clupload/cluploadEDU_osx.sh +tools.eduload.cmd.path.linux="{runtime.tools.sketchUploader-1.6.2+1.0.path}/clupload/cluploadEDU_linux.sh" +tools.eduload.cmd.path.windows={runtime.tools.sketchUploader-1.6.2+1.0.path}/x86/bin/bash.exe +tools.eduload.cmd.script.windows={runtime.tools.sketchUploader-1.6.2+1.0.path}/clupload/cluploadEDU_win.sh +tools.eduload.cmd.bin.windows={runtime.tools.sketchUploader-1.6.2+1.0.path}/x86/bin -tools.izmirdl.upload.params.verbose=-vvvvvv -tools.izmirdl.upload.params.quiet=-q +tools.eduload.upload.params.verbose=-vvvvvv +tools.eduload.upload.params.quiet=-q -tools.izmirdl.upload.pattern=/bin/bash --verbose --noprofile "{cmd.path}" "{runtime.ide.path}/hardware/tools/x86/bin" {build.path}/{build.project_name}.elf {serial.port} -tools.izmirdl.upload.pattern.linux=/bin/bash --verbose --noprofile {cmd.path} "{runtime.ide.path}/hardware/tools" {build.path}/{build.project_name}.elf {serial.port} -tools.izmirdl.upload.elf.windows={build.path}/{build.project_name}.elf -tools.izmirdl.upload.pattern.windows="{cmd.path}" "--verbose" "--noprofile" "{cmd.script}" "{cmd.bin}" "{upload.elf}" "{serial.port}" +tools.eduload.upload.pattern=/bin/bash --verbose --noprofile "{cmd.path}" "{runtime.tools.sketchUploader-1.6.2+1.0.path}/x86/bin" {build.path}/{build.project_name}.elf {serial.port} +tools.eduload.upload.pattern.linux=/bin/bash --verbose --noprofile {cmd.path} "{runtime.tools.sketchUploader-1.6.2+1.0.path}/x86/bin" {build.path}/{build.project_name}.elf {serial.port} +tools.eduload.upload.elf.windows={build.path}/{build.project_name}.elf +tools.eduload.upload.pattern.windows="{cmd.path}" "--verbose" "--noprofile" "{cmd.script}" "{cmd.bin}" "{upload.elf}" "{serial.port}" diff --git a/programmers.txt b/programmers.txt new file mode 100644 index 00000000..e69de29b diff --git a/system/libarc32_edu/Makefile b/system/libarc32_edu/Makefile new file mode 100644 index 00000000..e9143818 --- /dev/null +++ b/system/libarc32_edu/Makefile @@ -0,0 +1,82 @@ +ASM_SRC+=$(wildcard $(PWD)/bootcode/*.S) +ASM_SRC+=$(wildcard $(PWD)/drivers/*.S) +ASM_SRC+=$(wildcard $(PWD)/common/*.S) +C_SRC+=$(wildcard $(PWD)/bootcode/*.c) +C_SRC+=$(wildcard $(PWD)/drivers/*.c) +C_SRC+=$(wildcard $(PWD)/common/*.c) + +ARCH=ARC +CC=arc-elf32-gcc +AS=arc-elf32-as +LD=$(CC) +OC=arc-elf32-objcopy +RM=rm -f +INSTALL=install +BINVER=$(PWD)/build/add_binary_version_header.py + +BINVER_MAJOR=0 +BINVER_MINOR=0 +BINVER_PATCH=0 +BINVER_STRING=ATP1ARC000-1516C5527 + +TARGET=arc32drv_edu +TARGET_LIB=lib$(TARGET).a +TARGET_ELF=$(TARGET).elf +TARGET_BIN=$(TARGET).bin + +HWFLAGS=-mARCv2EM -mav2em -mlittle-endian +CFGFLAGS=-DCONFIG_SOC_GPIO_32 +OPTFLAGS=-g -Os -Wall +INCLUDES=-Icommon -Ibootcode +EXTRA_CFLAGS=-D__CPU_ARC__ -DCLOCK_SPEED=32 -fno-reorder-functions -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-defer-pop -Wno-unused-but-set-variable -Wno-main -ffreestanding -fno-stack-protector -mno-sdata -ffunction-sections -fdata-sections +CFLAGS=$(HWFLAGS) $(OPTFLAGS) $(EXTRA_CFLAGS) $(CFGFLAGS) $(INCLUDES) + +LDFLAGS=-nostartfiles -nodefaultlibs -nostdlib -static \ +-Wl,-X -Wl,-N -Wl,-mARCv2EM -Wl,-marcelf -Wl,--gc-sections \ +-Wl,-Map,$(TARGET_ELF).map \ +-Wl,--whole-archive $(TARGET_LIB) -Wl,--no-whole-archive \ +-Wl,--start-group -lc -lm -lgcc + +OCFLAGS=-S -O binary -R .note -R .comment -R COMMON -R .eh_frame + +LINKER_CMD_FILE=$(PWD)/build/linker.cmd + +C_OBJ=$(C_SRC:.c=.o) +ASM_OBJ=$(ASM_SRC:.S=.o) + +all: $(C_SRC) $(ASM_SRC) main.c $(TARGET_BIN) + +app: $(TARGET_BIN) + +lib: $(TARGET_LIB) + +$(TARGET_LIB): $(C_OBJ) $(ASM_OBJ) + @echo "Link $@" + $(AR) rcs $@ $^ + +$(TARGET_ELF): $(TARGET_LIB) main.o + @echo "Link $@" + $(LD) -T $(LINKER_CMD_FILE) $(LDFLAGS) -o $@ $^ + +$(TARGET_BIN): $(TARGET_ELF) + $(OC) $(OCFLAGS) $^ $@ + $(BINVER) --major $(BINVER_MAJOR) --minor $(BINVER_MINOR) --patch $(BINVER_PATCH) --version_string $(BINVER_STRING) $@ + +%.o: %.S + @echo "Assembling $<" + $(CC) -c $(CFLAGS) $< -o $@ + +%.o: %.c + @echo "Compiling $<" + $(CC) -c $(CFLAGS) $< -o $@ + +lib_install: lib + @if test "$(LIB_INSTALL_PATH)" = "" ; then \ + echo "LIB_INSTALL_PATH not set"; \ + exit 1; \ + else \ + $(INSTALL) $(TARGET_LIB) $(LIB_INSTALL_PATH); \ + fi \ + +clean: + -$(RM) $(C_OBJ) $(ASM_OBJ) $(TARGET_LIB) $(TARGET_ELF) $(TARGET_BIN) $(TARGET_ELF).map diff --git a/system/libarc32_edu/bootcode/c_init.c b/system/libarc32_edu/bootcode/c_init.c new file mode 100644 index 00000000..23f529b3 --- /dev/null +++ b/system/libarc32_edu/bootcode/c_init.c @@ -0,0 +1,64 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#include +#include + +#include "interrupt.h" + +/* Application main() function prototype */ +extern int main (void); + +/* C++ constructor function prototype */ +typedef void (*cpp_ctor_fn) (void); +/* C++ constructor list */ +extern cpp_ctor_fn __CTOR_LIST__[]; + +/* BSS section markers */ +extern char __bss_start[]; +extern char __bss_end[]; + +/* DATA section markers */ +extern char __data_rom_start[]; +extern char __data_ram_start[]; +extern char __data_ram_end[]; + +static void _exec_ctors (void) +{ + unsigned long i, nctors = (unsigned long)(__CTOR_LIST__[0]); + + for (i = nctors; i > 0; i--) + __CTOR_LIST__[i](); +} + + __attribute__((__noreturn__)) void _main (void) +{ + /* Zero BSS section */ + memset(__bss_start, 0, __bss_end - __bss_start); + /* Relocate DATA section to RAM */ + memcpy(__data_ram_start, __data_rom_start, __data_ram_end - __data_ram_start); + /* Execute C++ Constructors */ + _exec_ctors(); + /* Init the the interrupt unit device - disable all the interrupts; The + * default value of IRQ_ENABLE is 0x01 for all configured interrupts */ + interrupt_unit_device_init(); + /* Jump to application main() */ + main (); + /* Never reached */ + __builtin_unreachable(); +} diff --git a/system/libarc32_edu/bootcode/conf.h b/system/libarc32_edu/bootcode/conf.h new file mode 100644 index 00000000..300753eb --- /dev/null +++ b/system/libarc32_edu/bootcode/conf.h @@ -0,0 +1,35 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef _ARCV2_CONF__H_ +#define _ARCV2_CONF__H_ + + +#define _WRS_CONFIG_NUM_IRQS 64 + +#define _RAM_END (0xa8010000 + 0x4000) + +#define STACK_SIZE 1024 +#define ISR_STACK_SIZE 1024 + +#define ARCV2_IRQ_TIMER0 16 +#define ARCV2_IRQ_TIMER1 17 + + +#endif /* _ARCV2_CONF__H_ */ diff --git a/system/libarc32_edu/bootcode/init.S b/system/libarc32_edu/bootcode/init.S new file mode 100644 index 00000000..a0a34890 --- /dev/null +++ b/system/libarc32_edu/bootcode/init.S @@ -0,0 +1,60 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#include "aux_regs.h" + +.section .int_vector_table +.balign 4 +_start: + .word _do_reset +.rep 15 + .word _do_fault +.endr +.rep 52 + .word _do_isr +.endr + +.section .text +.balign 4 +_do_reset: + /* Ensure interrupts are initially disabled */ + clri + /* Switch to Interrupt Vector Table defined above*/ + mov r0, @_start + sr r0, [ARC_V2_IRQ_VECT_BASE] + /* Set up stack pointer */ +// mov sp, @_DefaultStack + STACK_SIZE + mov sp, @__stack_start + /* Enable instruction cache */ + mov r0, 0 + sr r0, [ARC_V2_IC_CTRL] + /* Configure the interrupt priority threshold of the ARC core to 3 */ + seti 0x23 + /* Jump to C init function */ + j @_main + +.balign 4 +_do_fault: + /* Set halt flag */ + flag 0x01 + nop + nop + nop + /* loop forever */ + j @_do_fault + nop diff --git a/system/libarc32_edu/bootcode/interrupt.c b/system/libarc32_edu/bootcode/interrupt.c new file mode 100644 index 00000000..47c7ca7c --- /dev/null +++ b/system/libarc32_edu/bootcode/interrupt.c @@ -0,0 +1,89 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#include "conf.h" +#include "aux_regs.h" +#include "interrupt.h" + +struct _IsrTableEntry +{ + void *arg; + void (*isr)(void *); +}; + +struct _IsrTableEntry __attribute__((section(".data"))) _IsrTable[_WRS_CONFIG_NUM_IRQS]; + +static void _dummy_isr(void *arg) +{ + for(;;); +} + +void interrupt_connect(unsigned int irq, + void (*isr)(void *arg), + void *arg) +{ + int index = irq - 16; + unsigned int flags = interrupt_lock(); + _IsrTable[index].isr = isr; + _IsrTable[index].arg = arg; + interrupt_unlock(flags); +} + +void interrupt_disconnect(unsigned int irq) +{ + int index = irq - 16; + _IsrTable[index].isr = _dummy_isr; +} + +void interrupt_enable(unsigned int irq) +{ + unsigned int flags = interrupt_lock(); + aux_reg_write (ARC_V2_IRQ_SELECT, irq); + aux_reg_write (ARC_V2_IRQ_PRIORITY, 1); + aux_reg_write (ARC_V2_IRQ_TRIGGER, ARC_V2_INT_LEVEL); + aux_reg_write (ARC_V2_IRQ_ENABLE, ARC_V2_INT_ENABLE); + interrupt_unlock(flags); +} + +void interrupt_disable(unsigned int irq) +{ + unsigned int flags = interrupt_lock(); + aux_reg_write (ARC_V2_IRQ_SELECT, irq); + aux_reg_write (ARC_V2_IRQ_ENABLE, ARC_V2_INT_DISABLE); + interrupt_unlock(flags); +} + +void interrupt_priority_set (int irq, unsigned char priority) +{ + unsigned int flags = interrupt_lock(); + aux_reg_write (ARC_V2_IRQ_SELECT, irq); + aux_reg_write (ARC_V2_IRQ_PRIORITY, priority); + interrupt_unlock(flags); +} + +void interrupt_unit_device_init(void) +{ + int irq_index; + for (irq_index = 16; irq_index < 256; irq_index++) + { + aux_reg_write(ARC_V2_IRQ_SELECT, irq_index); + aux_reg_write(ARC_V2_IRQ_PRIORITY, 1); + aux_reg_write(ARC_V2_IRQ_ENABLE, ARC_V2_INT_DISABLE); + aux_reg_write(ARC_V2_IRQ_TRIGGER, ARC_V2_INT_LEVEL); + } +} diff --git a/system/libarc32_edu/bootcode/interrupt.h b/system/libarc32_edu/bootcode/interrupt.h new file mode 100644 index 00000000..65d3e5d0 --- /dev/null +++ b/system/libarc32_edu/bootcode/interrupt.h @@ -0,0 +1,47 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +extern void interrupt_connect(unsigned int irq, + void (*isr)(void *arg), + void *arg); +extern void interrupt_disconnect(unsigned int irq); +extern void interrupt_enable(unsigned int irq); +extern void interrupt_disable(unsigned int irq); +extern void interrupt_priority_set (int irq, unsigned char priority); + +extern void interrupt_unit_device_init(void); + +static inline __attribute__((always_inline)) +unsigned int interrupt_lock(void) +{ + unsigned int key; + + __asm__ volatile ("clri %0" : "=r" (key)); + return key; +} + +static inline __attribute__((always_inline)) +void interrupt_unlock(unsigned int key) +{ + __asm__ volatile ("seti %0" :: "ir" (key)); +} + +#endif /* __INTERRUPT_H__ */ diff --git a/system/libarc32_edu/bootcode/irq.S b/system/libarc32_edu/bootcode/irq.S new file mode 100644 index 00000000..be347563 --- /dev/null +++ b/system/libarc32_edu/bootcode/irq.S @@ -0,0 +1,42 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#include "aux_regs.h" + +.globl _do_isr +.type _do_isr,%function + +.globl _IsrTable +.type _IsrTable,%object + +.text +.balign 4 +_do_isr: + lr r0, [ARC_V2_ICAUSE] + sub r0, r0, 16 + + mov r1, _IsrTable + add3 r0, r1, r0 /* table entries are 8-bytes wide */ + + ld r1, [r0, 4] /* ISR into r1 */ + jl_s.d [r1] + ld_s r0, [r0] /* delay slot: ISR parameter into r0 */ + + /* back from ISR */ + rtie + nop diff --git a/system/libarc32_edu/bootcode/version.c b/system/libarc32_edu/bootcode/version.c new file mode 100644 index 00000000..07d0502b --- /dev/null +++ b/system/libarc32_edu/bootcode/version.c @@ -0,0 +1,33 @@ +/* + * INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + */ + +#include "version.h" + +/* The content of this struct is overwritten in a post-build script */ +struct version_header version_header __attribute__((section(".version_header"))) = { + .magic = {'$', 'B', '!', 'N'}, + .version = 0x01, + .reserved_1 = {0, 0, 0, 0}, + .reserved_2 = {0, 0, 0, 0}, +}; diff --git a/system/libarc32_edu/bootcode/version.h b/system/libarc32_edu/bootcode/version.h new file mode 100644 index 00000000..0d48ba1d --- /dev/null +++ b/system/libarc32_edu/bootcode/version.h @@ -0,0 +1,108 @@ +/* + * INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + */ + +#ifndef __VERSION_H__ +#define __VERSION_H__ + +#include + +/** + * @addtogroup infra + * @{ + * @defgroup infra_version Binary Version Header Definition + * @} + * + * @addtogroup infra_version + * @{ + */ + +/** + * Define the content of a 48-bytes binary version header. + * + * The binary version header allows to uniquely identify the binary used. Note: + * - a device may include more than one binary, each having its own binary + * version header. + * - the position of this struct is usually defined in the linker script and + * its content is overwritten after the build (in a special post-build script). + * It therefore doesn't need to be initialized at compile-time (excepted magic + * and version), yet can be used in the code at runtime. + * + * The binary version header is usually localized at the beginning of + * the payload, but in the case of e.g. a bootloader, it can also be stored + * at the end of the payload, or even anywhere within the payload. + * + * Major, Minor, Patch are the following the usual definition, e.g. 1.0.0 + */ +struct version_header { + /** Always equal to $B!N */ + uint8_t magic[4]; + + /** Header format version */ + uint8_t version; + uint8_t major; + uint8_t minor; + uint8_t patch; + + /** + * Human-friendly version string, free format (not NULL terminated) + * Advised format is: PPPPXXXXXX-YYWWTBBBB + * - PPPP : product code, e.g ATP1 + * - XXXXXX: binary info. Usually contains information such as the + * binary type (bootloader, application), build variant (unit tests, + * debug, release), release/branch name + * - YY : year last 2 digits + * - WW : work week number + * - T : build type, e.g. [W]eekly, [L]atest, [R]elease, [P]roduction, + * [F]actory, [C]ustom + * - BBBB : build number, left padded with zeros + * Examples: + * - ATP1BOOT01-1503W0234 + * - CLRKAPP123-1502R0013 + */ + char version_string[20]; + + /** + * Micro-SHA1 (first 4 bytes of the SHA1) of the binary payload excluding + * this header. It allows to uniquely identify the exact binary used. + * In the case the header is located in the middle of the payload, the + * SHA1 has to be computed from two disjoint buffers. */ + uint8_t hash[4]; + + /** Position of the payload start relative to the address of this structure */ + int32_t offset; + + /** Filled with zeros, can be eventually used for 64 bits support */ + uint8_t reserved_1[4]; + + /** Size of the payload in bytes, including this header */ + uint32_t size; + + /** Filled with zeros, can be eventually used for 64 bits support */ + uint8_t reserved_2[4]; +} __packed; + +/** The global version header struct */ +extern struct version_header version_header; + +#endif /* __VERSION_H__ */ diff --git a/system/libarc32_edu/build/add_binary_version_header.py b/system/libarc32_edu/build/add_binary_version_header.py new file mode 100755 index 00000000..34abbed4 --- /dev/null +++ b/system/libarc32_edu/build/add_binary_version_header.py @@ -0,0 +1,145 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. +# +# The source code contained or described herein and all documents related to +# the source code ("Material") are owned by Intel Corporation or its suppliers +# or licensors. +# Title to the Material remains with Intel Corporation or its suppliers and +# licensors. +# The Material contains trade secrets and proprietary and confidential information +# of Intel or its suppliers and licensors. The Material is protected by worldwide +# copyright and trade secret laws and treaty provisions. +# No part of the Material may be used, copied, reproduced, modified, published, +# uploaded, posted, transmitted, distributed, or disclosed in any way without +# Intel's prior express written permission. +# +# No license under any patent, copyright, trade secret or other intellectual +# property right is granted to or conferred upon you by disclosure or delivery +# of the Materials, either expressly, by implication, inducement, estoppel or +# otherwise. +# +# Any license under such intellectual property rights must be express and +# approved by Intel in writing + +import ctypes +import sys +import argparse +import hashlib + +class BinaryVersionHeader(ctypes.Structure): + """Binary version header with $B!N magic, see declaration in + infra/version.h """ + _pack_ = 1 + _fields_ = [ + # Always equal to $B!N + ("magic", ctypes.c_char * 4), + + # Header format version + ("version", ctypes.c_ubyte), + ("major", ctypes.c_ubyte), + ("minor", ctypes.c_ubyte), + ("patch", ctypes.c_ubyte), + + # Human-friendly version string, free format (not NULL terminated) + # Advised format is: PPPPXXXXXX-YYWWTBBBB + # - PPPP : product code, e.g ATP1 + # - XXXXXX: binary info. Usually contains information such as the + # binary type (bootloader, application), build variant (unit tests, + # debug, release), release/branch name + # - YY : year last 2 digits + # - WW : work week number + # - T : build type, e.g. [Engineering], [W]eekly, [L]atest, + # [R]elease, [P]roduction, [F]actory, [C]ustom + # - BBBB : build number, left padded with zeros + # Examples: + # - ATP1BOOT01-1503W0234 + # - CLRKAPP123-1502R0013 + ("version_string", ctypes.c_ubyte * 20), + + # Micro-SHA1 (first 4 bytes of the SHA1) of the binary payload excluding + # this header. It allows to uniquely identify the exact binary used. + ("hash", ctypes.c_ubyte * 4), + + # Position of the payload relative to the address of this structure + ("offset", ctypes.c_int32), + ("reserved_1", ctypes.c_ubyte * 4), + + # Size of the payload, i.e. the full binary on which the hash was + # computed (excluding this header). The beginning of the payload + # is assumed to start right after the last byte of this structure. + ("size", ctypes.c_uint32), + ("reserved_2", ctypes.c_ubyte * 4) + ] + +MAGIC = "$B!N" + +def main(argv): + parser = argparse.ArgumentParser(description="""Overwrite the binary + version header in the passed binary file.""") + parser.add_argument('--major', dest='major', type=int, + help='major version number', required=True) + parser.add_argument('--minor', dest='minor', type=int, + help='minor version number', required=True) + parser.add_argument('--patch', dest='patch', type=int, + help='patch version number', required=True) + parser.add_argument('--version_string', dest='version_string', + help='human friendly version string, free format', required=True) + parser.add_argument('--header_position_hint', dest='header_position_hint', + type=str, help='one of start, end, unknown. Default to unknown.', + default="unknown") + parser.add_argument('input_file', + help='the binary file to modify in place') + args = parser.parse_args() + + arr = bytearray(open(args.input_file, "rb").read()) + + if args.header_position_hint == 'start': + header_pos = 0 + elif args.header_position_hint == 'end': + header_pos = len(arr)-48 + elif args.header_position_hint == 'unknown': + header_pos = arr.find(MAGIC) + if header_pos == -1: + raise Exception("Cannot find the magic string %s in the passed binary." % MAGIC) + else: + print "Found header magic at offset %x" % header_pos + else: + raise Exception("Invalid value for header_position_hint argument.") + + assert arr[header_pos:header_pos+4] == MAGIC + assert arr[header_pos+4] == 1 + + # Compute the hash. The header can be anywhere within the binary so we feed + # the generator in 2 passes + m = hashlib.sha1() + m.update(arr[0:header_pos]) + m.update(arr[header_pos+48:]) + digest = bytearray(m.digest()) + + # Create and initialize our header struct + bh = BinaryVersionHeader(MAGIC, 0x01) + assert len(bytearray(bh)) == 48 + bh.major = args.major + bh.minor = args.minor + bh.patch = args.patch + for i in range(0, 4): + bh.hash[i] = digest[i] + if len(args.version_string) < 20: + args.version_string += '\0' * (20-len(args.version_string)) + vs = bytearray(args.version_string) + for i in range(0, 20): + bh.version_string[i] = vs[i] + bh.offset = -header_pos + bh.size = len(arr) + + # Over-write the header content + arr[header_pos:header_pos+48] = bytearray(bh) + + # And save it + out_file = open(args.input_file, "wb") + out_file.write(arr) + +if __name__ == "__main__": + main(sys.argv) diff --git a/system/libarc32_edu/build/linker.cmd b/system/libarc32_edu/build/linker.cmd new file mode 100644 index 00000000..aec52454 --- /dev/null +++ b/system/libarc32_edu/build/linker.cmd @@ -0,0 +1,145 @@ +/* linker.cmd - Linker command/script file */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute, modify or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ + +/* +modification history +-------------------- +03Nov14,j_b written +16Apr15,dod trimmed down for Atlas-Edge version +*/ + +/* +DESCRIPTION +Linker script for the Atlas Peak ARC BSPs. +*/ + +OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") + +MEMORY + { + FLASH (rx) : ORIGIN = 0x40000000, LENGTH = 192K + SRAM (wx) : ORIGIN = 0xa8010000, LENGTH = 16K + DCCM (wx) : ORIGIN = 0x80000000, LENGTH = 8K + } + +/* Putting stack at end of SRAM for now */ +__stack_start = ORIGIN(SRAM)+LENGTH(SRAM); + +SECTIONS + { +/* FLASH Start */ + + version_header_section : + { + *(.version_header) + KEEP(*(".version_header*")) + } > FLASH + + text : ALIGN(1024) + { + __text_start = .; + +/* when !XIP, .text is in RAM, and vector table must be at its very start */ + KEEP(*(.int_vector_table)) + KEEP(*(".int_vector_table.*")) + + *(.text) + *(".text.*") + __text_end = .; + } > FLASH + + ctors : + { + /* + * The compiler fills the constructor pointers table below, hence symbol + * __ctor_table_start must be aligned on 4 byte boundary. + * To align with the C++ standard, the first element of the array + * contains the number of actual constructors. The last element is + * NULL. + */ + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + KEEP(*(SORT(".ctors*"))) + LONG(0) + __CTOR_END__ = .; + } > FLASH + + rodata : + { + *(.rodata) + *(".rodata.*") + } > FLASH + + __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ + +/* FLASH End */ + +/* SRAM Start */ + + datas : AT(__data_rom_start) + { + +/* when XIP, .text is in ROM, but vector table must be at start of .data */ + + __data_ram_start = .; + *(.data) + *(".data.*") + } > SRAM + + __data_ram_end = .; + + bss (NOLOAD) : + { + /* + * For performance, BSS section is assumed to be 4 byte aligned and + * a multiple of 4 bytes + */ + . = ALIGN(4); + __bss_start = .; + *(.bss) + *(".bss.*") + *(COMMON) + /* + * BSP clears this memory in words only and doesn't clear any + * potential left over bytes. + */ + __bss_end = ALIGN(4); + } > SRAM + + noinit (NOLOAD) : + { + /* + * This section is used for non-intialized objects that + * will not be cleared during the boot process. + */ + *(.noinit) + *(".noinit.*") + /* + * The seg_rxtx section is used by the Host IO module for + * allocating RX/TX buffers. If a specific memory location is + * required for these buffers, then a MEMORY definition should be + * made. + */ + *(.seg_rxtx) + *(".seg_rxtx.*") + } > SRAM + + /* Define linker symbols */ + + _end = .; /* end of image */ + +/* SRAM End */ + + /* Data Closely Coupled Memory (DCCM) */ +/* DCCM Start */ +/* DCCM End */ + + } diff --git a/system/libarc32_edu/common/aux_regs.h b/system/libarc32_edu/common/aux_regs.h new file mode 100644 index 00000000..7b00e968 --- /dev/null +++ b/system/libarc32_edu/common/aux_regs.h @@ -0,0 +1,86 @@ +/* aux_regs.h - ARCv2 auxiliary registers definitions */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute or otherwise make use of this software + * may be licensed only pursuant to the terms of an applicable Wind River + * license agreement. + */ + +/* +modification history +-------------------- +03nov14,bwa written +*/ + +/* +DESCRIPTION + +Definitions for auxiliary registers. +*/ + +#ifndef _ARC_V2_AUX_REGS__H_ +#define _ARC_V2_AUX_REGS__H_ + +#define ARC_V2_LP_START 0x002 +#define ARC_V2_LP_END 0x003 +#define ARC_V2_STATUS32 0x00a +#define ARC_V2_STATUS32_P0 0x00b +#define ARC_V2_AUX_IRQ_CTRL 0x00e +#define ARC_V2_IC_CTRL 0x011 +#define ARC_V2_TMR0_COUNT 0x021 +#define ARC_V2_TMR0_CONTROL 0x022 +#define ARC_V2_TMR0_LIMIT 0x023 +#define ARC_V2_IRQ_VECT_BASE 0x025 +#define ARC_V2_AUX_IRQ_ACT 0x043 +#define ARC_V2_TMR1_COUNT 0x100 +#define ARC_V2_TMR1_CONTROL 0x101 +#define ARC_V2_TMR1_LIMIT 0x102 +#define ARC_V2_IRQ_PRIO_PEND 0x200 +#define ARC_V2_AUX_IRQ_HINT 0x201 +#define ARC_V2_IRQ_PRIORITY 0x206 +#define ARC_V2_ERET 0x400 +#define ARC_V2_ERSTATUS 0x402 +#define ARC_V2_ECR 0x403 +#define ARC_V2_EFA 0x404 +#define ARC_V2_ICAUSE 0x40a +#define ARC_V2_IRQ_SELECT 0x40b +#define ARC_V2_IRQ_ENABLE 0x40c +#define ARC_V2_IRQ_TRIGGER 0x40d +#define ARC_V2_IRQ_STATUS 0x40f +#define ARC_V2_IRQ_PULSE_CANCEL 0x415 +#define ARC_V2_IRQ_PENDING 0x416 + +/* STATUS32/STATUS32_P0 bits */ +#define ARC_V2_STATUS32_H (1 << 0) +#define ARC_V2_STATUS32_E(x) ((x) << 1) +#define ARC_V2_STATUS32_AE_BIT 5 +#define ARC_V2_STATUS32_AE (1 << ARC_V2_STATUS32_AE_BIT) +#define ARC_V2_STATUS32_DE (1 << 6) +#define ARC_V2_STATUS32_U (1 << 7) +#define ARC_V2_STATUS32_V (1 << 8) +#define ARC_V2_STATUS32_C (1 << 9) +#define ARC_V2_STATUS32_N (1 << 10) +#define ARC_V2_STATUS32_Z (1 << 11) +#define ARC_V2_STATUS32_L (1 << 12) +#define ARC_V2_STATUS32_DZ (1 << 13) +#define ARC_V2_STATUS32_SC (1 << 14) +#define ARC_V2_STATUS32_ES (1 << 15) +#define ARC_V2_STATUS32_RB(x) ((x) << 16) +#define ARC_V2_STATUS32_IE (1 << 31) + +#define ARC_V2_INT_DISABLE 0 +#define ARC_V2_INT_ENABLE 1 +#define ARC_V2_INT_LEVEL 0 +#define ARC_V2_INT_PULSE 1 + +/* exception cause register masks */ +#define ARC_V2_ECR_VECTOR(X) ((X & 0xff0000) >> 16) +#define ARC_V2_ECR_CODE(X) ((X & 0xff00) >> 8) +#define ARC_V2_ECR_PARAMETER(X) (X & 0xff) + +#define aux_reg_read(reg) __builtin_arc_lr(reg) +#define aux_reg_write(reg, val) __builtin_arc_sr((unsigned int)val, reg) + +#endif /* _ARC_V2_AUX_REGS__H_ */ diff --git a/system/libarc32_edu/common/compiler.h b/system/libarc32_edu/common/compiler.h new file mode 100644 index 00000000..4eafacb1 --- /dev/null +++ b/system/libarc32_edu/common/compiler.h @@ -0,0 +1,24 @@ +/* aux_regs.h - ARCv2 auxiliary registers definitions */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute or otherwise make use of this software + * may be licensed only pursuant to the terms of an applicable Wind River + * license agreement. + */ + +#ifndef _COMPILER_H__ +#define _COMPILER_H__ + +#ifdef __GNUC__ + +#define _Usually(x) __builtin_expect(!!((x)), 1) +#define _Rarely(x) __builtin_expect(!!((x)), 0) +#define _sr(_src_, _reg_) __builtin_arc_sr((unsigned int)_src_, _reg_) +#define _lr(_reg_) __builtin_arc_lr(_reg_) +#define _nop() + +#endif + +#endif diff --git a/system/libarc32_edu/common/data_type.h b/system/libarc32_edu/common/data_type.h new file mode 100644 index 00000000..f973d464 --- /dev/null +++ b/system/libarc32_edu/common/data_type.h @@ -0,0 +1,62 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef DATA_TYPE_H_ +#define DATA_TYPE_H_ + +#include +#include + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef uint8_t boolean_t; +typedef volatile uint32_t * io_register_t; + +/*! + * Common driver function return codes + */ +typedef enum { + DRV_RC_OK = 0, + DRV_RC_FAIL, + DRV_RC_TIMEOUT, + DRV_RC_INVALID_CONFIG, /*!< configuration parameters incorrect */ + DRV_RC_MODE_NOT_SUPPORTED, /*!< controller/driver doesn't support this mode (master/slave) */ + DRV_RC_CONTROLLER_IN_USE, /*!< controller is in use */ + DRV_RC_CONTROLLER_NOT_ACCESSIBLE, /*!< controller not accessible from this core */ + DRV_RC_INVALID_OPERATION, /*!< attempt to perform an operation that is invalid */ + DRV_RC_WRITE_PROTECTED, /*!< Attempt to erase/program a memory region that is write protected */ + DRV_RC_READ_PROTECTED, /*!< Attempt to read a memory region that is read protected */ + DRV_RC_CHECK_FAIL, /*!< Read back data after programming does not match the word written to memory */ + DRV_RC_OUT_OF_MEM, /*!< Attempt to program data outside the memory boundaries */ + DRV_RC_ERASE_PC, /*!< Attempt to write/erase executable code currently in use */ + DRV_RC_TOTAL_RC_CODE /*!< Number of DRIVER_API_RC codes (used to extend this enum) */ +} DRIVER_API_RC; + +#endif diff --git a/system/libarc32_edu/common/portable.h b/system/libarc32_edu/common/portable.h new file mode 100644 index 00000000..22d1890c --- /dev/null +++ b/system/libarc32_edu/common/portable.h @@ -0,0 +1,72 @@ +/* aux_regs.h - ARCv2 auxiliary registers definitions */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute or otherwise make use of this software + * may be licensed only pursuant to the terms of an applicable Wind River + * license agreement. + */ + +#ifndef __PORTABLE_H__ +#define __PORTABLE_H__ + +#include "soc_register.h" +#include "../bootcode/interrupt.h" + +#define DECLARE_INTERRUPT_HANDLER +#define SET_INTERRUPT_HANDLER(_vec_, _isr_) \ + do { \ + interrupt_connect((_vec_), (_isr_), NULL); \ + interrupt_enable((_vec_)); \ + } while(0) + +#define WRITE_ARC_REG(value, reg) \ + __builtin_arc_sr(value, (volatile uint32_t)reg) + +#define READ_ARC_REG(reg) \ + __builtin_arc_lr((volatile uint32_t)reg) + +#define CLEAR_ARC_BIT(reg, bit) \ + do { \ + uint32_t saved = interrupt_lock(); \ + WRITE_ARC_REG(READ_ARC_REG(reg) & ~(1 << bit), reg); \ + interrupt_unlock(saved); \ + } while(0) + +#define SET_ARC_BIT(reg, bit) \ + do { \ + uint32_t saved = interrupt_lock(); \ + WRITE_ARC_REG(READ_ARC_REG(reg) | (1 << bit), reg); \ + interrupt_unlock(saved); \ + } while(0) + +#define CLEAR_MMIO_BIT(reg, bit) \ + do { \ + uint32_t saved = interrupt_lock(); \ + MMIO_REG_VAL(reg) &= ~(1 << bit); \ + interrupt_unlock(saved); \ + } while(0) + +#define SET_MMIO_BIT(reg, bit) \ + do { \ + uint32_t saved = interrupt_lock(); \ + MMIO_REG_VAL(reg) |= (1 << bit); \ + interrupt_unlock(saved); \ + } while(0) + +#define CLEAR_MMIO_MASK(reg, mask) \ + do { \ + uint32_t saved = interrupt_lock(); \ + MMIO_REG_VAL(reg) &= ~(mask); \ + interrupt_unlock(saved); \ + } while(0) + +#define SET_MMIO_MASK(reg, mask) \ + do { \ + uint32_t saved = interrupt_lock(); \ + MMIO_REG_VAL(reg) |= (mask); \ + interrupt_unlock(saved); \ + } while(0) + +#endif diff --git a/system/libarc32_edu/common/scss_registers.h b/system/libarc32_edu/common/scss_registers.h new file mode 100644 index 00000000..246e6da1 --- /dev/null +++ b/system/libarc32_edu/common/scss_registers.h @@ -0,0 +1,410 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef SCSS_REGISTERS_H_ +#define SCSS_REGISTERS_H_ + +#include + +/* MMIO Register Access Macros. */ +#define MMIO_REG_VAL(addr) (*((volatile uint32_t *)(addr))) +#define MMIO_REG_ADDR(addr) ((volatile uint32_t *)(addr)) +#define MMIO_REG_VAL_FROM_BASE(base, offset) \ + (*((volatile uint32_t *)((base)+(offset)))) + +#define CALC_PIN_MUX_SELECT_VAL(pin_offset, mode) (mode << pin_offset * 2) + +/* Pin Muxing */ +/* TODO: DB - Change these to offsets from SCSS */ +#define QRK_PMUX_PULLUP_0 0XB0800900 +#define QRK_PMUX_PULLUP_1 0XB0800904 +#define QRK_PMUX_PULLUP_2 0XB0800908 +#define QRK_PMUX_PULLUP_3 0XB080090C +#define QRK_PMUX_SELECT_0 0XB0800930 +#define QRK_PMUX_SELECT_1 0XB0800934 +#define QRK_PMUX_SELECT_2 0XB0800938 +#define QRK_PMUX_SELECT_3 0XB080093C +#define QRK_PMUX_SELECT_4 0XB0800940 +#define QRK_PMUX_SELECT_5 0XB0800948 + +#define QRK_PMUX_SEL_MODEA 0 +#define QRK_PMUX_SEL_MODEB 1 +#define QRK_PMUX_SEL_MODEC 2 +#define QRK_PMUX_SEL_MODED 3 + +#define SCSS_REGISTER_BASE 0xB0800000 +#define SCSS_REG_VAL(offset) \ + MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, offset) + +#define SCSS_OSC0_CFG0 0x0 /* Hybrid Oscillator Config 0 */ +#define SCSS_OSC0_STAT1 0x4 /* Hybrid Oscillator Status 1 */ +#define SCSS_OSC0_CFG1 0x8 /* Hybrid Oscillator Config 1 */ + +#define OSC0_CFG1_XTAL_OSC_EN_MASK (1 << 0) +#define OSC0_CFG1_XTAL_OSC_OUT_MASK (1 << 3) + +#define SCSS_CCU_SYS_CLK_CTL_OFFSET 0x38 +#define SCSS_CCU_RTC_CLK_DIV_EN (1 << 2) +#define SCSS_RTC_CLK_DIV_1_SECOND 0x78 + +/* Interrupt masking */ +#define QRK_INT_UNMASK_IA (~0x00000001) + +#define SCSS_INT_GPIO_MASK_OFFSET 0X46C +#define SCSS_INT_PWM_TIMER_MASK_OFFSET 0X470 +#define SCSS_INT_RTC_MASK_OFFSET 0x478 +#define SCSS_INT_WATCHDOG_MASK_OFFSET 0x47C +#define SCSS_INT_MPR_MASK_OFFSET 0x4BC +#define SCSS_INT_MAILBOX_MASK 0x4A0 +#define QRK_INT_PWM_UNMASK_LMT (~0x1) +#define QRK_INT_WDT_UNMASK_LMT (~0x1) +#define QRK_INT_RTC_UNMASK_LMT (~0x1) +#define QRK_INT_MPR_UNMASK_LMT (~0x1) +#define QRK_INT_MPR_UNMASK_LMT_HLT (~0x10000) +#define QRK_SCSS_P_STS 0x560 +#define QRK_SCSS_P_STS_HIR_PRBE_MODE_EN (1 << 26) +#define QRK_SCSS_PERIPH_CFG0_OFFSET 0x804 +#define QRK_SCSS_PERIPH_CFG0_WDT_ENABLE (1 << 1) +/* Identification */ +#define SCSS_ID 0x0128 +/* Revision */ +#define SCSS_REV 0x012C +/* Sensor Subsystem */ +#define SCSS_SS_CFG 0x0600 +#define SCSS_SS_STS 0x0604 +#define ARC_HALT_REQ_A (1 << 25) +#define ARC_RUN_REQ_A (1 << 24) +/* Always On Counter */ +#define SCSS_AONC_CNT 0x0700 +#define SCSS_AONC_CFG 0x0704 +#define AONC_CNT_DIS 0 +#define AONC_CNT_EN 1 +/* Mailbox Channel Status */ +#define SCSS_MBOX_CHALL_STS 0x0AC0 + +/* Clock Gating */ +/* TODO: DB - Change these to offsets from SCSS */ +#define QRK_CLKGATE_CTRL 0xB0800018 +#define QRK_CLKGATE_CTRL_WDT_ENABLE (1 << 10) +#define QRK_CLKGATE_CTRL_RTC_ENABLE (1 << 11) +#define QRK_CLKGATE_CTRL_PWM_ENABLE (1 << 12) + +#define PERIPH_CLK_GATE_CTRL (SCSS_REGISTER_BASE + 0x018) + +/* PWM */ +#define QRK_PWM_BASE_ADDR 0xB0000800 +#define QRK_PWM_N_REGS_LEN 0x14 +#define QRK_PWM_N_LCNT2_LEN 0x04 + +/* PWM register offsets */ +#define QRK_PWM_N_LOAD_COUNT1 0x00 +#define QRK_PWM_N_CURRENT_VALUE 0x04 +#define QRK_PWM_N_CONTROL 0x08 +#define QRK_PWM_N_EOI 0x0C +#define QRK_PWM_N_INT_STATUS 0x10 +#define QRK_PWM_N_LOAD_COUNT2 0xB0 + +#define QRK_PWMS_INT_STATUS 0xA0 +#define QRK_PWMS_EOI 0xA4 +#define QRK_PWMS_RAW_INT_STATUS 0xA8 +#define QRK_PWMS_COMP_VERSION 0xAC + +#define QRK_PWM_CONTROL_ENABLE (1 << 0) +#define QRK_PWM_CONTROL_MODE_PERIODIC (1 << 1) +#define QRK_PWM_CONTROL_INT_MASK (1 << 2) +#define QRK_PWM_CONTROL_PWM_OUT (1 << 3) + +/* soc GPIOs */ +#define SOC_GPIO_BASE_ADDR 0xB0000C00 +#define SOC_GPIO_AON_BASE_ADDR (SCSS_REGISTER_BASE + 0xB00) +#define SOC_GPIO_SWPORTA_DR 0x00 +#define SOC_GPIO_SWPORTA_DDR 0x04 +#define SOC_GPIO_SWPORTA_CTL 0x08 +#define SOC_GPIO_INTEN 0x30 +#define SOC_GPIO_INTMASK 0x34 +#define SOC_GPIO_INTTYPE_LEVEL 0x38 +#define SOC_GPIO_INTPOLARITY 0x3c +#define SOC_GPIO_INTSTATUS 0x40 +#define SOC_GPIO_RAW_INTSTATUS 0x44 +#define SOC_GPIO_DEBOUNCE 0x48 +#define SOC_GPIO_PORTA_EOI 0x4c +#define SOC_GPIO_EXT_PORTA 0x50 +#define SOC_GPIO_LS_SYNC 0x60 +#define SOC_GPIO_INT_BOTHEDGE 0x68 +#define SOC_GPIO_CONFIG_REG2 0x70 +#define SOC_GPIO_CONFIG_REG1 0x74 + +/* ARC GPIOs */ +#define SS_GPIO_8B0_BASE_ADDR 0x80017800 +#define SS_GPIO_8B1_BASE_ADDR 0x80017900 +#define SS_GPIO_SWPORTA_DR 0x00 +#define SS_GPIO_SWPORTA_DDR 0x01 +#define SS_GPIO_INTEN 0x03 +#define SS_GPIO_INTMASK 0x04 +#define SS_GPIO_INTTYPE_LEVEL 0x05 +#define SS_GPIO_INT_POLARITY 0x06 +#define SS_GPIO_INTSTATUS 0x07 +#define SS_GPIO_DEBOUNCE 0x08 +#define SS_GPIO_PORTA_EOI 0x09 +#define SS_GPIO_EXT_PORTA 0x0a +#define SS_GPIO_LS_SYNC 0x0b + +/* Watchdog Timer */ +#define QRK_WDT_CRR_VAL 0x76 + +#define QRK_WDT_BASE_ADDR 0xB0000000 +#define QRK_WDT_CR 0x00 +#define QRK_WDT_TORR 0x04 +#define QRK_WDT_CCVR 0x08 +#define QRK_WDT_CRR 0x0C +#define QRK_WDT_STAT 0x10 +#define QRK_WDT_EOI 0x14 +#define QRK_WDT_COMP_PARAM_5 0xE4 +#define QRK_WDT_COMP_PARAM_4 0xE8 +#define QRK_WDT_COMP_PARAM_3 0xEC +#define QRK_WDT_COMP_PARAM_2 0xF0 +#define QRK_WDT_COMP_PARAM_1 0xF4 +#define QRK_WDT_COMP_VERSION 0xF8 +#define QRK_WDT_COMP_TYPE 0xFC + +#define QRK_WDT_CR_ENABLE (1 << 0) +#define QRK_WDT_CR_INT_ENABLE (1 << 1) /* interrupt mode enable - mode1*/ + +/* RTC */ +#define QRK_RTC_BASE_ADDR 0xB0000400 +#define QRK_RTC_CCVR 0x00 +#define QRK_RTC_CMR 0x04 +#define QRK_RTC_CLR 0x08 +#define QRK_RTC_CCR 0x0C +#define QRK_RTC_STAT 0x10 +#define QRK_RTC_RSTAT 0x14 +#define QRK_RTC_EOI 0x18 +#define QRK_RTC_COMP_VERSION 0x1C + +#define QRK_RTC_INTERRUPT_ENABLE (1 << 0) +#define QRK_RTC_INTERRUPT_MASK (1 << 1) +#define QRK_RTC_ENABLE (1 << 2) +#define QRK_RTC_WRAP_ENABLE (1 << 3) + +/* MPR */ +#define QRK_MPR_BASE_ADDR 0xB0400000 +#define QRK_MPR_REGS_LEN 0x04 +#define QRK_MPR_MAX_NUM 3 /* 4 MPRs 0-3) */ +#define QRK_MPR_CFG_LOCK (1 << 31) +#define QRK_MPR_CFG_EN (1 << 30) +#define QRK_MPR_CFG_HOST_WRITE_EN (1 << 20) +#define QRK_MPR_CFG_SS_WRITE_EN (1 << 21) +#define QRK_MPR_CFG_OTHER_WRITE_EN (1 << 22) +#define QRK_MPR_CFG_HOST_READ_EN (1 << 24) +#define QRK_MPR_CFG_SS_READ_EN (1 << 25) +#define QRK_MPR_CFG_OTHER_READ_EN (1 << 26) +#define QRK_MPR0_CFG 0x00 +#define QRK_MPR1_CFG 0x04 +#define QRK_MPR2_CFG 0x08 +#define QRK_MPR3_CFG 0x0C +#define QRK_MPR_VDATA 0x10 +#define QRK_MPR_VSTS 0x14 + +/* I2C */ +#define SOC_I2C_0_BASE (0xb0002800) +#define SOC_I2C_1_BASE (0xb0002c00) + +/* SPI */ +#define SOC_MST_SPI0_REGISTER_BASE (0xB0001000) +#define SOC_MST_SPI1_REGISTER_BASE (0xB0001400) +#define SOC_SLV_SPI_REGISTER_BASE (0xB0001800) + +/* Mailbox Interrupt*/ +#define IO_REG_MAILBOX_INT_MASK (SCSS_REGISTER_BASE + 0x4A0) + +/* Mailbox Base Address */ +#define IO_REG_MAILBOX_BASE (SCSS_REGISTER_BASE + 0xA00) + +/* Mailbox offsets */ +#define MAILBOX_CTRL_OFFSET (0x00) +#define MAILBOX_DATA0_OFFSET (0x04) +#define MAILBOX_DATA1_OFFSET (0x08) +#define MAILBOX_DATA2_OFFSET (0x0C) +#define MAILBOX_DATA3_OFFSET (0x10) +#define MAILBOX_STATUS_OFFSET (0x14) + +/* Mailbox addresses for a given index */ +#define MBX_CTRL(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_CTRL_OFFSET)) +#define MBX_DAT0(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_DATA0_OFFSET)) +#define MBX_DAT1(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_DATA1_OFFSET)) +#define MBX_DAT2(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_DATA2_OFFSET)) +#define MBX_DAT3(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_DATA3_OFFSET)) +#define MBX_STS(_x_) MMIO_REG_VAL( \ + (IO_REG_MAILBOX_BASE + (0x18*(_x_)) + MAILBOX_STATUS_OFFSET)) + +#define MBX_CHALL_STS SCSS_REG_VAL(SCSS_MBOX_CHALL_STS) + +/* DMAC Interrupts Mask Register Offsets */ +#define INT_DMA_CHANNEL_0_MASK_REG (0x480) +#define INT_DMA_CHANNEL_1_MASK_REG (0x484) +#define INT_DMA_CHANNEL_2_MASK_REG (0x488) +#define INT_DMA_CHANNEL_3_MASK_REG (0x48C) +#define INT_DMA_CHANNEL_4_MASK_REG (0x490) +#define INT_DMA_CHANNEL_5_MASK_REG (0x494) +#define INT_DMA_CHANNEL_6_MASK_REG (0x498) +#define INT_DMA_CHANNEL_7_MASK_REG (0x49C) +#define INT_DMA_ERROR_MASK_REG (0x4B8) + +/* Pin Muxing */ +#define PULLUP_BASE QRK_PMUX_PULLUP_0 +/* Read current pull-up reg, Zero pin bit, OR new mode into these bits, write reg - thereby preserving other pin mode settings */ +#define SET_PULLUP_REG( mux_reg, enable, pin ) MMIO_REG_VAL(mux_reg) = ( MMIO_REG_VAL(mux_reg) & ~( 1 << (pin) ) ) | ( enable << (pin) ) +/* Calculate mux register address from pin number and calculate pin number within that register - call SET_MUX_REG */ +#define SET_PIN_PULLUP( pin_no, enable) SET_PULLUP_REG( (((pin_no/32)*4 )+ MUX_BASE), enable, pin_no % 32) + +#define MUX_BASE QRK_PMUX_SELECT_0 +/* Read current Mux reg, Zero pin bits, OR new mode into these bits, write reg - thereby preserving other pin mode settings */ +#define SET_MUX_REG( mux_reg, mode, pin ) MMIO_REG_VAL(mux_reg) = ( MMIO_REG_VAL(mux_reg) & ~( 3 << (pin*2) ) ) | ( mode << (pin*2) ) +/* Calculate mux register address from pin number and calculate pin number within that register - call SET_MUX_REG */ +#define SET_PIN_MODE( pin_no, mode) SET_MUX_REG( (((pin_no/16)*4 )+ MUX_BASE), mode, pin_no % 16) + + +#define AHB_CTRL_REG (SCSS_REGISTER_BASE + 0x034) + +/* Typical value used to unmask single source interrupts in SCSS. */ +#define ENABLE_SSS_INTERRUPTS ~(0x00000001 << 8) +#define DISABLE_SSS_INTERRUPTS (0x00000001 << 8) + + +/* Latest Masks */ +#define INT_SS_ADC_ERR_MASK (0x400) /* Sensor Subsystem Interrupt Routing Mask 0 */ +#define INT_SS_ADC_IRQ_MASK (0x404) /* Sensor Subsystem Interrupt Routing Mask 1 */ +#define INT_SS_GPIO_0_INTR_MASK (0x408) /* Sensor Subsystem Interrupt Routing Mask 2 */ +#define INT_SS_GPIO_1_INTR_MASK (0x40C) /* Sensor Subsystem Interrupt Routing Mask 3 */ +#define INT_SS_I2C_0_ERR_MASK (0x410) /* Sensor Subsystem Interrupt Routing Mask 4 */ +#define INT_SS_I2C_0_RX_AVAIL_MASK (0x414) /* Sensor Subsystem Interrupt Routing Mask 5 */ +#define INT_SS_I2C_0_TX_REQ_MASK (0x418) /* Sensor Subsystem Interrupt Routing Mask 6 */ +#define INT_SS_I2C_0_STOP_DETECTED_MASK (0x41C) /* Sensor Subsystem Interrupt Routing Mask 7 */ +#define INT_SS_I2C_1_ERR_MASK (0x420) /* Sensor Subsystem Interrupt Routing Mask 8 */ +#define INT_SS_I2C_1_RX_AVAIL_MASK (0x424) /* Sensor Subsystem Interrupt Routing Mask 9 */ +#define INT_SS_I2C_1_TX_REQ_MASK (0x428) /* Sensor Subsystem Interrupt Routing Mask 10 */ +#define INT_SS_I2C_1_STOP_DETECTED_MASK (0x42C) /* Sensor Subsystem Interrupt Routing Mask 11 */ +#define INT_SS_SPI_0_ERR_INT_MASK (0x430) /* Sensor Subsystem Interrupt Routing Mask 12 */ +#define INT_SS_SPI_0_RX_AVAIL_MASK (0x434) /* Sensor Subsystem Interrupt Routing Mask 13 */ +#define INT_SS_SPI_0_TX_REQ_MASK (0x438) /* Sensor Subsystem Interrupt Routing Mask 14 */ +#define INT_SS_SPI_1_ERR_INT_MASK (0x43C) /* Sensor Subsystem Interrupt Routing Mask 15 */ +#define INT_SS_SPI_1_RX_AVAIL_MASK (0x440) /* Sensor Subsystem Interrupt Routing Mask 16 */ +#define INT_SS_SPI_1_TX_REQ_MASK (0x444) /* Sensor Subsystem Interrupt Routing Mask 17 */ + +#define INT_I2C_MST_0_MASK (0x448) /* Host Processor Interrupt Routing Mask 0 */ +#define INT_I2C_MST_1_MASK (0x44C) /* Host Processor Interrupt Routing Mask 1 */ +#define INT_SPI_MST_0_MASK (0x454) /* Host Processor Interrupt Routing Mask 2 */ +#define INT_SPI_MST_1_MASK (0x458) /* Host Processor Interrupt Routing Mask 3 */ +#define INT_SPI_SLV_MASK (0x45C) /* Host Processor Interrupt Routing Mask 4 */ +#define INT_UART_0_MASK (0x460) /* Host Processor Interrupt Routing Mask 5 */ +#define INT_UART_1_MASK (0x464) /* Host Processor Interrupt Routing Mask 6 */ +#define INT_I2S_MASK (0x468) /* Host Processor Interrupt Routing Mask 7 */ +#define INT_GPIO_MASK (0x46C) /* Host Processor Interrupt Routing Mask 8 */ +#define INT_PWM_TIMER_MASK (0x470) /* Host Processor Interrupt Routing Mask 9 */ +#define INT_USB_MASK (0x474) /* Host Processor Interrupt Routing Mask 10 */ +#define INT_RTC_MASK (0x478) /* Host Processor Interrupt Routing Mask 11 */ +#define INT_WATCHDOG_MASK (0x47C) /* Host Processor Interrupt Routing Mask 12 */ +#define INT_DMA_CHANNEL_0_MASK (0x480) /* Host Processor Interrupt Routing Mask 13 */ +#define INT_DMA_CHANNEL_1_MASK (0x484) /* Host Processor Interrupt Routing Mask 14 */ +#define INT_DMA_CHANNEL_2_MASK (0x488) /* Host Processor Interrupt Routing Mask 15 */ +#define INT_DMA_CHANNEL_3_MASK (0x48C) /* Host Processor Interrupt Routing Mask 16 */ +#define INT_DMA_CHANNEL_4_MASK (0x490) /* Host Processor Interrupt Routing Mask 17 */ +#define INT_DMA_CHANNEL_5_MASK (0x494) /* Host Processor Interrupt Routing Mask 18 */ +#define INT_DMA_CHANNEL_6_MASK (0x498) /* Host Processor Interrupt Routing Mask 19 */ +#define INT_DMA_CHANNEL_7_MASK (0x49C) /* Host Processor Interrupt Routing Mask 20 */ +#define INT_MAILBOX_MASK (0x4A0) /* Host Processor Interrupt Routing Mask 21 */ +#define INT_COMPARATORS_SS_HALT_MASK (0x4A4) /* Host Processor Interrupt Routing Mask 22 */ +#define INT_COMPARATORS_HOST_HALT_MASK (0x4A8) /* Host Processor Interrupt Routing Mask 23 */ +#define INT_COMPARATORS_SS_MASK (0x4AC) /* Host Processor Interrupt Routing Mask 24 */ +#define INT_COMPARATORS_HOST_MASK (0x4B0) /* Host Processor Interrupt Routing Mask 25 */ +#define INT_SYSTEM_PMU_MASK (0x4B4) /* Host Processor Interrupt Routing Mask 26 */ +#define INT_DMA_ERROR_MASK (0x4B8) /* Host Processor Interrupt Routing Mask 27 */ +#define INT_SRAM_CONTROLLER_MASK (0x4BC) /* Host Processor Interrupt Routing Mask 28 */ +#define INT_FLASH_CONTROLLER_0_MASK (0x4C0) /* Host Processor Interrupt Routing Mask 29 */ +#define INT_FLASH_CONTROLLER_1_MASK (0x4C4) /* Host Processor Interrupt Routing Mask 30 */ +#define INT_AON_TIMER_MASK (0x4C8) /* Host Processor Interrupt Routing Mask 31 */ +#define INT_ADC_PWR_MASK (0x4CC) /* Host Processor Interrupt Routing Mask 32 */ +#define INT_ADC_CALIB_MASK (0x4D0) /* Host Processor Interrupt Routing Mask 33 */ +#define INT_AON_GPIO_MASK (0x4D4) /* Host Processor Interrupt Routing Mask 34 */ +#define LOCK_INT_MASK_REG (0x4D8) /* Interrupt Mask Lock Register */ + +/* sticky registers */ +#define SCSS_GPS0 0x100 +#define SCSS_GPS1 0x104 +#define SCSS_GPS2 0x108 +#define SCSS_GPS3 0x10C + +/* SCSS Mailbox Interrupt masking/unmasking */ +#ifdef __CPU_LMT__ +/* First byte of the register is for the Lakemont */ +#define SCSS_INT_MAILBOX_START_CHANNEL 0x00 +#elif __CPU__ARC__ +/* Second byte is for ARC */ +#define SCSS_INT_MAILBOX_START_CHANNEL 0x10 +#endif + +#define SOC_MBX_INT_UNMASK(channel) SCSS_REG_VAL(SCSS_INT_MAILBOX_MASK) &= \ + ~( 1 << ( channel + SCSS_INT_MAILBOX_START_CHANNEL ) ) +#define SOC_MBX_INT_MASK(channel) SCSS_REG_VAL(SCSS_INT_MAILBOX_MASK) |= \ + ( 1 << ( channel + SCSS_INT_MAILBOX_START_CHANNEL ) ) + +/* Interrupt vector mapping */ +#ifdef __CPU_LMT__ +#define SOC_I2C0_INTERRUPT 0x0 +#define SOC_I2C1_INTERRUPT 0x1 +#define SOC_SPIM0_INTERRUPT 0x2 +#define SOC_SPIM1_INTERRUPT 0x3 +#define SOC_SPIS0_INTERRUPT 0x4 +#define SOC_UART0_INTERRUPT 0x5 +#define SOC_UART1_INTERRUPT 0x6 +#define SOC_GPIO_INTERRUPT 0x8 +#define SOC_PWM_INTERRUPT 0x9 +#define SOC_RTC_INTERRUPT 0xb +#define SOC_WDT_INTERRUPT 0xc +#define SOC_MBOX_INTERRUPT 0x15 +#define SOC_MPR_INTERRUPT 0x19 +#define SOC_GPIO_AON_INTERRUPT 0x1F + +#define SOC_UNMASK_INTERRUPTS(_driver_) (MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, _driver_) &= QRK_INT_UNMASK_IA) +#endif + +#ifdef __CPU_ARC__ +#define SOC_I2C0_INTERRUPT (36) +#define SOC_I2C1_INTERRUPT (37) +#define SOC_SPIM0_INTERRUPT (38) +#define SOC_SPIM1_INTERRUPT (39) +#define SOC_SPIS0_INTERRUPT (40) +#define SOC_GPIO_INTERRUPT (44) +#define SOC_PWM_INTERRUPT (45) +#define SOC_GPIO_AON_INTERRUPT (67) + +#define SOC_UNMASK_INTERRUPTS(_driver_) (MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, _driver_) &= ENABLE_SSS_INTERRUPTS) +#endif + +#endif /* SCSS_REGISTERS_H_ */ diff --git a/system/libarc32_edu/common/soc_register.h b/system/libarc32_edu/common/soc_register.h new file mode 100644 index 00000000..6b660866 --- /dev/null +++ b/system/libarc32_edu/common/soc_register.h @@ -0,0 +1,73 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef SOC_REGISTER_H_ +#define SOC_REGISTER_H_ + +#include "scss_registers.h" + +/* + * CREG defines + */ +#define CREG_CLK_CTRL_SPI0 (27) +#define CREG_CLK_CTRL_SPI1 (28) +#define CREG_CLK_CTRL_I2C0 (29) +#define CREG_CLK_CTRL_I2C1 (30) +#define CREG_CLK_CTRL_ADC (31) + +/* PVP */ +#define PVP_REGISTER_BASE (0xB0600000) + +#define IO_REG_PVP_NCR (PVP_REGISTER_BASE + 0x00) +#define IO_REG_PVP_COMP (PVP_REGISTER_BASE + 0x04) +#define IO_REG_PVP_LCOMP (PVP_REGISTER_BASE + 0x08) +#define IO_REG_PVP_IDX_DIST (PVP_REGISTER_BASE + 0x0C) +#define IO_REG_PVP_CAT (PVP_REGISTER_BASE + 0x10) +#define IO_REG_PVP_AIF (PVP_REGISTER_BASE + 0x14) +#define IO_REG_PVP_MINIF (PVP_REGISTER_BASE + 0x18) +#define IO_REG_PVP_MAXIF (PVP_REGISTER_BASE + 0x1C) +#define IO_REG_PVP_TESTCOMP (PVP_REGISTER_BASE + 0x20) +#define IO_REG_PVP_TESTCAT (PVP_REGISTER_BASE + 0x24) +#define IO_REG_PVP_NID (PVP_REGISTER_BASE + 0x28) +#define IO_REG_PVP_GCR (PVP_REGISTER_BASE + 0x2C) +#define IO_REG_PVP_RSTCHAIN (PVP_REGISTER_BASE + 0x30) +#define IO_REG_PVP_NSR (PVP_REGISTER_BASE + 0x34) +#define IO_REG_PVP_FORGET_NCOUNT (PVP_REGISTER_BASE + 0x3C) + + +#define IO_REG_PVP_TESTCOMP (PVP_REGISTER_BASE + 0x20) +#define IO_REG_PVP_TESTCAT (PVP_REGISTER_BASE + 0x24) +#define IO_REG_PVP_NID (PVP_REGISTER_BASE + 0x28) +#define IO_REG_PVP_GCR (PVP_REGISTER_BASE + 0x2C) +#define IO_REG_PVP_RSTCHAIN (PVP_REGISTER_BASE + 0x30) +#define IO_REG_PVP_NSR (PVP_REGISTER_BASE + 0x34) +#define IO_REG_PVP_FORGET_NCOUNT (PVP_REGISTER_BASE + 0x3C) + +/* DMAC Base address */ +#define DMAC_REGISTER_BASE (0xB0700000) + +#define AUX_INTERRUPT_CAUSE (0x40a) +#define AUX_EXCEPTION_CAUSE (0x403) + +#endif diff --git a/system/libarc32_edu/drivers/adc_priv.h b/system/libarc32_edu/drivers/adc_priv.h new file mode 100644 index 00000000..10e1dd25 --- /dev/null +++ b/system/libarc32_edu/drivers/adc_priv.h @@ -0,0 +1,124 @@ +/* +* +* CONFIDENTIAL AND PROPRIETARY INFORMATION +* +* Copyright (c) 2013 Synopsys, Inc. All rights reserved. +* This software and documentation contain confidential and +* proprietary information that is the property of +* Synopsys, Inc. The software and documentation are +* furnished under a license agreement and may be used +* or copied only in accordance with the terms of the license +* agreement. No part of the software and documentation +* may be reproduced, transmitted, or translated, in any +* form or by any means, electronic, mechanical, manual, +* optical, or otherwise, without prior written permission +* of Synopsys, Inc., or as expressly provided by the license agreement. +* Reverse engineering is prohibited, and reproduction, +* disclosure or use without specific written authorization +* of Synopsys Inc. is strictly forbidden. +*/ + + +#ifndef ADC_PRIV_H_ +#define ADC_PRIV_H_ + + +/* EAI ADC device registers */ +#define ADC_SET (0x00) +#define ADC_DIVSEQSTAT (0x01) +#define ADC_SEQ (0x02) +#define ADC_CTRL (0x03) +#define ADC_INTSTAT (0x04) +#define ADC_SAMPLE (0x05) + + +/* ADC Specific macros */ +#define ADC_POP_SAMPLE (0x80000000) +#define ADC_FLUSH_RX (0x40000000) +#define ADC_FTL_SET_MASK (0x00ffffff) /* FIFO threshold level */ +#define ADC_SEQ_SIZE_SET_MASK (0x3fc0ffff) +#define ADC_SEQ_MODE_SET_MASK (0x3fffdfff) +#define ADC_CONFIG_SET_MASK (0x3fffe000) +#define ADC_CLK_RATIO_MASK (0x1fffff) +#define ADC_CLR_UNDRFLOW (1 << 18) +#define ADC_CLR_OVERFLOW (1 << 17) +#define ADC_CLR_DATA_A (1 << 16) +#define ADC_SEQ_TABLE_RST (0x0040) +#define ADC_SEQ_PTR_RST (0x0020) +#define ADC_SEQ_START (0x0010) +#define ADC_SEQ_STOP_MASK (0x078ec) +#define ADC_INT_ENA_MASK (0x001e) +#define ADC_INT_DSB (0x0F00) +#define ADC_INT_ENABLE (0x0000) +#define ADC_CLK_ENABLE (0x0004) +#define ADC_ENABLE (0x0002) +#define ADC_DISABLE (0x0) +#define ADC_RESET (0x1) +#define ADC_INT_DATA_A (0x1) +#define ADC_INT_ERR (0x6) + +#define ADC_STATE_CLOSED 0 +#define ADC_STATE_DISABLED 1 +#define ADC_STATE_IDLE 2 +#define ADC_STATE_SAMPLING 3 + + +#define BUFS_NUM (2) + + +/* ADC control commands */ +#define IO_ADC_SET_CLK_DIVIDER (0x20) +#define IO_ADC_SET_CONFIG (0x21) +#define IO_ADC_SET_SEQ_TABLE (0x22) +#define IO_ADC_SET_SEQ_MODE (0x23) +#define IO_ADC_SET_SEQ_STOP (0x24) +#define IO_ADC_SET_RX_THRESHOLD (0x25) + +#define IO_ADC_INPUT_SINGLE_END 0 +#define IO_ADC_INPUT_DIFF 1 +#define IO_ADC_OUTPUT_PARAL 0 +#define IO_ADC_OUTPUT_SERIAL 1 +#define IO_ADC_CAPTURE_RISING_EDGE 0 +#define IO_ADC_CAPTURE_FALLING_EDGE 1 + +#define IO_ADC_SEQ_MODE_SINGLESHOT 0 +#define IO_ADC_SEQ_MODE_REPETITIVE 1 + + +#define REG_WRITE( reg, x ) _sr( (unsigned)(x), (unsigned)(dev->reg_base + reg) ) +#define REG_READ( reg ) _lr( (unsigned)(dev->reg_base + reg) ) + + +typedef void (* ISR)(); +typedef void (* IO_CB_FUNC)( uint32_t ); + + +typedef struct adc_info_struct +{ + uint32_t reg_base; /* base address of device register set */ + uint8_t instID; + uint8_t state; + uint8_t seq_mode; + uint8_t index; + uint32_t seq_size; + uint32_t rx_len; + uint32_t * rx_buf[BUFS_NUM]; + uint32_t * res_size[BUFS_NUM]; + /* Callbacks */ + IO_CB_FUNC rx_cb; + IO_CB_FUNC err_cb; + /* Interrupt numbers and handlers */ + uint8_t rx_vector; /* ISR vectors */ + uint8_t err_vector; + ISR rx_isr; /* ADC device ISRs */ + ISR err_isr; + uint16_t fifo_tld; + uint16_t fifo_depth; + /* SSS Interrupt Routing Mask Registers */ + uint32_t adc_irq_mask; + uint32_t adc_err_mask; + void * priv; +} adc_info_t, *adc_info_pt; + + +#endif /* ADC_PRIV_H_ */ diff --git a/system/libarc32_edu/drivers/arcv2_timer1.c b/system/libarc32_edu/drivers/arcv2_timer1.c new file mode 100644 index 00000000..254f7ece --- /dev/null +++ b/system/libarc32_edu/drivers/arcv2_timer1.c @@ -0,0 +1,224 @@ +/* arcv2_timer1.c - ARC timer 1 device driver */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute, modify or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ + +/* +modification history +-------------------- +03Nov14,j_b written +*/ + +/* +DESCRIPTION +This module implements a VxMicro device driver for the ARCv2 processor timer 1 + +\INTERNAL IMPLEMENTATION DETAILS +The ARCv2 processor timer provides a 32-bit incrementing, wrap-to-zero counter. + +The device driver is also part of a nanokernel-only system, but omits more +complex capabilities (such as tickless idle support) that are only used in +conjunction with a microkernel. +*/ + + +#include "arcv2_timer1.h" +#include "aux_regs.h" +#include "conf.h" +#include "../bootcode/interrupt.h" + +#define ARCV2_TIMER1_CLOCK_FREQ 32000000 /* 32MHz reference clock */ + +/* defines */ + +#define ARC_V2_TMR_CTRL_IE 0x1 /* interrupt enable */ +#define ARC_V2_TMR_CTRL_NH 0x2 /* count only while not halted */ +#define ARC_V2_TMR_CTRL_W 0x4 /* watchdog mode enable */ +#define ARC_V2_TMR_CTRL_IP 0x8 /* interrupt pending flag */ + +/* globals */ + +void (* timer1_user_int_handler)(void) = 0x00; + +/* locals */ + +/* forward declarations */ + +uint32_t timer1_read(void); + +/******************************************************************************* +* +* arcv2_timer_enable - enable the timer with the given limit/countup value +* +* This routine sets up the timer for operation by: +* - setting value to which the timer will count up to; +* - setting the timer's start value to zero; and +* - enabling interrupt generation. +* +* RETURNS: N/A +* +* \NOMANUAL +*/ + +static inline __attribute__((always_inline)) +void arcv2_timer_enable + ( + uint32_t count /* count to which timer is to increment to */ + ) +{ + aux_reg_write(ARC_V2_TMR1_LIMIT, count); /* write the limit value */ + /* count only when not halted for debug and enable interrupts */ + aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE); + aux_reg_write(ARC_V2_TMR1_COUNT, 0); /* write the start value */ +} + +/******************************************************************************* +* +* arcv2_timer_count_get - get the current counter value +* +* This routine gets the value from the timer's count register. This +* value is the 'time' elapsed from the starting count (assumed to be 0). +* +* RETURNS: the current counter value +* +* \NOMANUAL +*/ +static inline __attribute__((always_inline)) +uint32_t arcv2_timer1_count_get(void) +{ + return (aux_reg_read(ARC_V2_TMR1_COUNT)); +} + +/******************************************************************************* + * + * arcv2_timer_limit_get - get the limit/countup value + * + * This routine gets the value from the timer's limit register, which is the + * value to which the timer will count up to. + * + * RETURNS: the current counter value + * + * \NOMANUAL + */ +static inline __attribute__((always_inline)) +uint32_t arcv2_timer1_limit_get(void) +{ + return (aux_reg_read(ARC_V2_TMR1_LIMIT)); +} + +/******************************************************************************* +* +* _arcv2_timer_int_handler - system clock periodic tick handler +* +* This routine handles the system clock periodic tick interrupt. A TICK_EVENT +* event is pushed onto the microkernel stack. +* +* RETURNS: N/A +* +* \NOMANUAL +*/ +void _arcv2_timer1_int_handler(void *notused) +{ + (void)(notused); + /* clear the interrupt (by writing 0 to IP bit of the control register) */ + aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE); + /* execute callback specified by the user */ + if (0x00 != timer1_user_int_handler) + timer1_user_int_handler(); +} + + +/******************************************************************************* +* +* timer_driver - initialize timer1 and enable interrupt +* +* RETURNS: N/A +*/ + +void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms) +{ + int tickunit; + + /* ensure that the timer will not generate interrupts */ + aux_reg_write(ARC_V2_TMR1_CONTROL, 0); + aux_reg_write(ARC_V2_TMR1_COUNT, 0); /* clear the count value */ + + /* connect specified routine/parameter to the timer 0 interrupt vector */ + interrupt_connect(ARCV2_IRQ_TIMER1, _arcv2_timer1_int_handler, 0); + timer1_user_int_handler = int_handler; +#if 0 + (void) nanoCpuIntConnect(_WRS_CONFIG_ARCV2_TIMER1_INT_LVL, + _WRS_CONFIG_ARCV2_TIMER1_INT_PRI, + _arcv2_timer1_int_handler, 0); +#endif + + tickunit = (ARCV2_TIMER1_CLOCK_FREQ / 1000) * ticktime_ms; + + /* + * Set the reload value to achieve the configured tick rate, enable the + * counter and interrupt generation. + * + * The global variable 'tickunit' represents the #cycles/tick. + */ + + arcv2_timer_enable(tickunit); + + /* Everything has been configured. It is now safe to enable the interrupt */ + interrupt_enable(ARCV2_IRQ_TIMER1); + /* Enable global ARC interrupts */ +// interrupt_unlock(ARCV2_SETI_IRQ_LVL_2); + interrupt_unlock(0); +#if 0 + nanoCpuIntEnable (_WRS_CONFIG_ARCV2_TIMER1_INT_LVL); +#endif +} + +/******************************************************************************* +* +* timer_read - read the BSP timer hardware +* +* This routine returns the current time in terms of timer hardware clock cycles. +* +* RETURNS: up counter of elapsed clock cycles +*/ + +uint32_t timer1_read(void) +{ + return arcv2_timer1_count_get(); +} + + +/******************************************************************************* +* +* timer_disable - stop announcing ticks into the kernel +* +* This routine disables timer interrupt generation and delivery. +* Note that the timer's counting cannot be stopped by software. +* +* RETURNS: N/A +*/ + +void timer1_disable(void) +{ + uint32_t saved; + uint32_t ctrl_val; /* timer control register value */ + + saved = interrupt_lock(); + + /* disable interrupt generation */ + ctrl_val = aux_reg_read(ARC_V2_TMR0_CONTROL); + aux_reg_write(ARC_V2_TMR0_CONTROL, ctrl_val & ~ARC_V2_TMR_CTRL_IE); + + interrupt_unlock(saved); + + /* disable interrupt in the interrupt controller */ + interrupt_disable(ARCV2_IRQ_TIMER1); +#if 0 + nanoCpuIntDisable (ARCV2_IRQ_TIMER1); +#endif +} diff --git a/system/libarc32_edu/drivers/arcv2_timer1.h b/system/libarc32_edu/drivers/arcv2_timer1.h new file mode 100644 index 00000000..75f38154 --- /dev/null +++ b/system/libarc32_edu/drivers/arcv2_timer1.h @@ -0,0 +1,35 @@ +/* arcv2_timer1.c - ARC timer 1 device driver */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute, modify or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ + +#ifndef _ARCV2_TIMER1__H_ +#define _ARCV2_TIMER1__H_ + +#include + + +/******************************************************************************* +* +* timer_driver - initialize timer1 and enable interrupt +* +* RETURNS: N/A +*/ + +#ifdef __cplusplus + extern "C" { +#endif + +void timer1_driver_init(void(*int_handler)(void), uint32_t ticktime_ms); +uint32_t timer1_read(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARCV2_TIMER1__H_ */ diff --git a/system/libarc32_edu/drivers/common_i2c.h b/system/libarc32_edu/drivers/common_i2c.h new file mode 100644 index 00000000..1389d41c --- /dev/null +++ b/system/libarc32_edu/drivers/common_i2c.h @@ -0,0 +1,103 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ +/* + * Intel common I2C header + * + */ + +#ifndef COMMON_I2C_H_ +#define COMMON_I2C_H_ + +/** + * \addtogroup common_driver + * @{ + * \defgroup common_driver I2C: Inter Integrated Communication bus API + * @{ + * \brief Definition of the structure and functions used by I2C ARC and SOC Drivers implementation. + */ + +/*!< +API types +*/ +typedef enum { + I2C_OK = 0, + I2C_BUSY, + I2C_TX_ABORT, + I2C_TX_OVER, + I2C_RX_OVER, + I2C_RX_UNDER, +}DRIVER_I2C_STATUS_CODE; + +/*! + * I2C speeds + */ +typedef enum { + I2C_SLOW = 1, /*!< (1) 0-100 Khz - note: Starts at 1 to remove need to translate before hardware write */ + I2C_FAST = 2, /*!< (2) 400 Khz */ + I2C_HS = 3 /*!< (3) 3400 kbit/s mode added support for HS mode available only in SoC block */ +} I2C_SPEED; + +/*! + * I2C addressing modes + */ +typedef enum { + I2C_7_Bit = 0, /*!< (0) 7 bit */ + I2C_10_Bit, /*!< (1) 10 bit */ +} I2C_ADDR_MODE; + +/*! + * I2C mode types + */ +typedef enum { + I2C_MASTER = 0, + I2C_SLAVE +} I2C_MODE_TYPE; + +/*! +* \brief callback function signature +*/ +typedef void (*i2c_callback)( uint32_t ); /*!< callback function signature */ + + +/*! +* \brief I2C controller configuration. +* Driver instantiates one of these with given parameters for each I2C +* controller configured using the "ss_i2c_set_config" function +*/ +typedef struct i2c_cfg_data{ + I2C_SPEED speed; + I2C_ADDR_MODE addressing_mode; /*!< 7 bit / 10 bit addressing */ + I2C_MODE_TYPE mode_type; /*!< Master or Slave */ + uint32_t slave_adr; /*!< I2C address if configured as a Slave */ + i2c_callback cb_rx; /*!< callback function for notification of data received and available to application, NULL if callback not required by application code */ + uint32_t cb_rx_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ + i2c_callback cb_tx /*!< callback function for notification of transmit completion by the I2C controller, NULL if callback not required by application code */; + uint32_t cb_tx_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ + i2c_callback cb_err; /*!< callback function on transaction error, NULL if callback not required by application code */ + uint32_t cb_err_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ +}i2c_cfg_data_t; + +/**@} @}*/ + +#endif /* COMMON_I2C_H_ */ \ No newline at end of file diff --git a/system/libarc32_edu/drivers/common_spi.h b/system/libarc32_edu/drivers/common_spi.h new file mode 100644 index 00000000..e04ecc7a --- /dev/null +++ b/system/libarc32_edu/drivers/common_spi.h @@ -0,0 +1,134 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ +/* + * Intel common SPI header + * + */ + +#ifndef COMMON_SPI_H_ +#define COMMON_SPI_H_ + +/** + * \addtogroup common_driver + * @{ + * \defgroup common_driver SPI: Serial Peripheral API + * @{ + * \brief Definition of the structure and functions used by SPI ARC and SOC Drivers implementation. + */ + +/*! + * Driver status return codes + */ +typedef enum { + SPI_OK = 0, + SPI_BUSY, + SPI_TFE, /* TX FIFO Empty */ + SPI_RFNE /* RX FIFO Not Empty */ +}DRIVER_SPI_STATUS_CODE; + +/*! + * SPI Bus Modes + */ +typedef enum { /*!< Mode Clk Polarity Clk Phase */ + SPI_BUSMODE_0 = 0x00, /*!< 0 0 0 */ + SPI_BUSMODE_1 = 0x01, /*!< 1 0 1 */ + SPI_BUSMODE_2 = 0x02, /*!< 2 1 0 */ + SPI_BUSMODE_3 = 0x03 /*!< 3 1 1 */ +}SPI_BUS_MODE; + +/*! + * SPI Transfer modes + */ +typedef enum { + SPI_TX_RX = 0, + SPI_TX_ONLY, + SPI_RX_ONLY, + SPI_EPROM_RD +}SPI_TRANSFER_MODE; + +/*! + * Slave selects + */ +typedef enum { + SPI_NO_SE = 0, + SPI_SE_1 = 0x01, + SPI_SE_2 = 0x02, + SPI_SE_3 = 0x04, + SPI_SE_4 = 0x08 +}SPI_SLAVE_ENABLE; + +/*! + * Data frame sizes + */ +typedef enum { + SPI_4_BIT = 3, /*!< starts at 3 because values less than this are reserved */ + SPI_5_BIT = 4, + SPI_6_BIT = 5, + SPI_7_BIT = 6, + SPI_8_BIT = 7, + SPI_9_BIT = 8, + SPI_10_BIT = 9, + SPI_11_BIT = 10, + SPI_12_BIT = 11, + SPI_13_BIT = 12, + SPI_14_BIT = 13, + SPI_15_BIT = 14, + SPI_16_BIT = 15 +}SPI_DATA_FRAME_SIZE; + +/*! + * SPI mode types + */ +typedef enum { + SPI_MASTER = 0, + SPI_SLAVE +} SPI_MODE_TYPE; + +/*! +* \brief callback function signature +*/ +typedef void (*spi_callback)( uint32_t ); /*!< callback function signature */ + +/*! +* \brief SPI controller configuration. +* Driver instantiates one of these with given parameters for each SPI +* controller configured using the "ss_spi_set_config" function +*/ +typedef struct spi_cfg_data{ + uint32_t speed; /*!< SPI bus speed in KHz */ + SPI_TRANSFER_MODE txfr_mode; /*!< Transfer mode */ + SPI_DATA_FRAME_SIZE data_frame_size; /*!< Data Frame Size ( 4 - 16 bits ) */ + SPI_SLAVE_ENABLE slave_enable; /*!< Slave Enable ( 0 = none - possibly used for Slaves that are selected by GPIO ) */ + SPI_BUS_MODE bus_mode; /*!< See SPI_BUS_MODE above for description */ + spi_callback cb_xfer /*!< callback function for notification of transmit completion by the SPI controller, NULL if callback not required by application code */; + uint32_t cb_xfer_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ + spi_callback cb_err; /*!< callback function on transaction error, NULL if callback not required by application code */ + uint32_t cb_err_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ + uint8_t loopback_enable; /*!< (ONLY available for SOC) this will enable loopback mode on spi module */ + spi_callback cb_slave_rx; /*!< (ONLY available for SOC) callback funciton for slave mode on spi module */ +}spi_cfg_data_t; + +/**@} @}*/ + +#endif /* COMMON_SPI_H_ */ \ No newline at end of file diff --git a/system/libarc32_edu/drivers/eiaextensions.h b/system/libarc32_edu/drivers/eiaextensions.h new file mode 100644 index 00000000..ca3b35f5 --- /dev/null +++ b/system/libarc32_edu/drivers/eiaextensions.h @@ -0,0 +1,962 @@ + +/* **** DO NOT EDIT - this file is generated by ARChitect2 **** + * + * Description: Header file declaring the compiler extensions for eia components + */ + +#ifndef _eiaextensions_H_ +#define _eiaextensions_H_ + +#ifndef __GNUC__ + +// User extension aux register - dsp_mac +#define AR_DSP_MAC_MSBOUT 0x80000000 +#pragma aux_register(AR_DSP_MAC_MSBOUT, name => "ar_dsp_mac_msbout") +#define AR_DSP_MAC_LSBOUT 0x80000001 +#pragma aux_register(AR_DSP_MAC_LSBOUT, name => "ar_dsp_mac_lsbout") + +// User extension instruction - dmulh11 +extern long dmulh11(long, long); +#pragma intrinsic(dmulh11, opcode => 0x06, sub_opcode => 0x08 , blocking_cycles => 7) + +// User extension instruction - dmulh11_f +extern long dmulh11_f(long, long); +#pragma intrinsic(dmulh11_f, opcode => 0x06, sub_opcode => 0x08, set_flags => 1, flags => "zncv" , blocking_cycles => 7) + +// User extension instruction - fmul +extern long fmul(long, long); +#pragma intrinsic(fmul, opcode => 0x06, sub_opcode => 0x00 , latency_cycles => 3) + +// User extension instruction - fmul_f +extern long fmul_f(long, long); +#pragma intrinsic(fmul_f, opcode => 0x06, sub_opcode => 0x00, set_flags => 1, flags => "zncv" , latency_cycles => 3) + +// User extension instruction - alg2 +extern long alg2(long); +#pragma intrinsic(alg2, opcode => 0x07, sub_opcode => 0x20 ) + +// User extension instruction - alg2_f +extern long alg2_f(long); +#pragma intrinsic(alg2_f, opcode => 0x07, sub_opcode => 0x20, set_flags => 1, flags => "zncv" ) + +// User extension instruction - mulcc +extern long mulcc(long, long); +#pragma intrinsic(mulcc, opcode => 0x07, sub_opcode => 0x00 , latency_cycles => 2) + +// User extension instruction - mulcc_f +extern long mulcc_f(long, long); +#pragma intrinsic(mulcc_f, opcode => 0x07, sub_opcode => 0x00, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dsp_abs_1d +extern long dsp_abs_1d(long); +#pragma intrinsic(dsp_abs_1d, opcode => 0x07, sub_opcode => 0x00 ) + +// User extension instruction - dsp_add_1d +extern long dsp_add_1d(long, long); +#pragma intrinsic(dsp_add_1d, opcode => 0x07, sub_opcode => 0x03 ) + +// User extension instruction - dsp_fp_cmp +extern long dsp_fp_cmp(long, long); +#pragma intrinsic(dsp_fp_cmp, opcode => 0x07, sub_opcode => 0x2b ) + +// User extension instruction - dsp_fp_cmp_f +extern long dsp_fp_cmp_f(long, long); +#pragma intrinsic(dsp_fp_cmp_f, opcode => 0x07, sub_opcode => 0x2b, set_flags => 1, flags => "zncv" ) + +// User extension instruction - dsp_fp_div +extern long dsp_fp_div(long, long); +#pragma intrinsic(dsp_fp_div, opcode => 0x07, sub_opcode => 0x2a , blocking_cycles => 2) + +// User extension instruction - dsp_fp_flt2i +extern long dsp_fp_flt2i(long); +#pragma intrinsic(dsp_fp_flt2i, opcode => 0x07, sub_opcode => 0x2b ) + +// User extension instruction - dsp_fp_i2flt +extern long dsp_fp_i2flt(long); +#pragma intrinsic(dsp_fp_i2flt, opcode => 0x07, sub_opcode => 0x2c ) + +// User extension instruction - dsp_fp_sqrt +extern long dsp_fp_sqrt(long); +#pragma intrinsic(dsp_fp_sqrt, opcode => 0x07, sub_opcode => 0x2d , blocking_cycles => 3) + +// User extension instruction - dsp_mac +extern long dsp_mac(long, long); +#pragma intrinsic(dsp_mac, opcode => 0x07, sub_opcode => 0x1B , effects => "ar_dsp_mac_msbout:is_read;ar_dsp_mac_lsbout:is_read;ar_dsp_mac_msbout:is_written;ar_dsp_mac_lsbout:is_written") + +// User extension instruction - dsp_negate_1d +extern long dsp_negate_1d(long); +#pragma intrinsic(dsp_negate_1d, opcode => 0x07, sub_opcode => 0x0F ) + +// User extension instruction - dsp_shift_1d +extern long dsp_shift_1d(long, long); +#pragma intrinsic(dsp_shift_1d, opcode => 0x07, sub_opcode => 0x18 ) + +// User extension instruction - dsp_cos +extern long dsp_cos(long); +#pragma intrinsic(dsp_cos, opcode => 0x07, sub_opcode => 0x1E , blocking_cycles => 7) + +// User extension instruction - dsp_sub_1d +extern long dsp_sub_1d(long, long); +#pragma intrinsic(dsp_sub_1d, opcode => 0x07, sub_opcode => 0x06 ) + +// User extension instruction - lg2 +extern long lg2(long); +#pragma intrinsic(lg2, opcode => 0x07, sub_opcode => 0x21 ) + +// User extension instruction - lg2_f +extern long lg2_f(long); +#pragma intrinsic(lg2_f, opcode => 0x07, sub_opcode => 0x21, set_flags => 1, flags => "zncv" ) + +// User extension instruction - mpy16x16_ll +extern long mpy16x16_ll(long, long); +#pragma intrinsic(mpy16x16_ll, opcode => 0x07, sub_opcode => 0x3e , latency_cycles => 2) + +// User extension instruction - mpy16x16_ll_f +extern long mpy16x16_ll_f(long, long); +#pragma intrinsic(mpy16x16_ll_f, opcode => 0x07, sub_opcode => 0x3e, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - scgexpj +extern long scgexpj(long, long); +#pragma intrinsic(scgexpj, opcode => 0x07, sub_opcode => 0x10 , latency_cycles => 2) + +// User extension instruction - dmulh12 +extern long dmulh12(long, long); +#pragma intrinsic(dmulh12, opcode => 0x06, sub_opcode => 0x09 , blocking_cycles => 7) + +// User extension instruction - dmulh12_f +extern long dmulh12_f(long, long); +#pragma intrinsic(dmulh12_f, opcode => 0x06, sub_opcode => 0x09, set_flags => 1, flags => "zncv" , blocking_cycles => 7) + +// User extension instruction - fadd +extern long fadd(long, long); +#pragma intrinsic(fadd, opcode => 0x06, sub_opcode => 0x01 , latency_cycles => 3) + +// User extension instruction - fadd_f +extern long fadd_f(long, long); +#pragma intrinsic(fadd_f, opcode => 0x06, sub_opcode => 0x01, set_flags => 1, flags => "zncv" , latency_cycles => 3) + +// User extension instruction - mulrcc +extern long mulrcc(long, long); +#pragma intrinsic(mulrcc, opcode => 0x07, sub_opcode => 0x01 , latency_cycles => 2) + +// User extension instruction - mulrcc_f +extern long mulrcc_f(long, long); +#pragma intrinsic(mulrcc_f, opcode => 0x07, sub_opcode => 0x01, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dsp_abs_2d +extern long dsp_abs_2d(long); +#pragma intrinsic(dsp_abs_2d, opcode => 0x07, sub_opcode => 0x01 ) + +// User extension instruction - dsp_add_2d +extern long dsp_add_2d(long, long); +#pragma intrinsic(dsp_add_2d, opcode => 0x07, sub_opcode => 0x04 ) + +// User extension instruction - dsp_mult +extern long dsp_mult(long, long); +#pragma intrinsic(dsp_mult, opcode => 0x07, sub_opcode => 0x1C , effects => "ar_dsp_mac_msbout:is_written;ar_dsp_mac_lsbout:is_written") + +// User extension instruction - dsp_negate_2d +extern long dsp_negate_2d(long); +#pragma intrinsic(dsp_negate_2d, opcode => 0x07, sub_opcode => 0x10 ) + +// User extension instruction - dsp_shift_2d +extern long dsp_shift_2d(long, long); +#pragma intrinsic(dsp_shift_2d, opcode => 0x07, sub_opcode => 0x19 ) + +// User extension instruction - dsp_sin +extern long dsp_sin(long); +#pragma intrinsic(dsp_sin, opcode => 0x07, sub_opcode => 0x1F , blocking_cycles => 7) + +// User extension instruction - dsp_sub_2d +extern long dsp_sub_2d(long, long); +#pragma intrinsic(dsp_sub_2d, opcode => 0x07, sub_opcode => 0x07 ) + +// User extension instruction - mac16x16_ll +extern long mac16x16_ll(long, long); +#pragma intrinsic(mac16x16_ll, opcode => 0x07, sub_opcode => 0x37 , latency_cycles => 2) + +// User extension instruction - mac16x16_ll_f +extern long mac16x16_ll_f(long, long); +#pragma intrinsic(mac16x16_ll_f, opcode => 0x07, sub_opcode => 0x37, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - scgexpnj +extern long scgexpnj(long, long); +#pragma intrinsic(scgexpnj, opcode => 0x07, sub_opcode => 0x11 , latency_cycles => 2) + +// User extension instruction - dsubh21 +extern long dsubh21(long, long); +#pragma intrinsic(dsubh21, opcode => 0x06, sub_opcode => 0x12 , blocking_cycles => 5) + +// User extension instruction - dsubh21_f +extern long dsubh21_f(long, long); +#pragma intrinsic(dsubh21_f, opcode => 0x06, sub_opcode => 0x12, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - fsub +extern long fsub(long, long); +#pragma intrinsic(fsub, opcode => 0x06, sub_opcode => 0x02 , latency_cycles => 3) + +// User extension instruction - fsub_f +extern long fsub_f(long, long); +#pragma intrinsic(fsub_f, opcode => 0x06, sub_opcode => 0x02, set_flags => 1, flags => "zncv" , latency_cycles => 3) + +// User extension instruction - macdwe +extern long macdwe(long, long); +#pragma intrinsic(macdwe, opcode => 0x07, sub_opcode => 0x16 , latency_cycles => 2) + +// User extension instruction - macdwe_f +extern long macdwe_f(long, long); +#pragma intrinsic(macdwe_f, opcode => 0x07, sub_opcode => 0x16, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dsp_abs_4d +extern long dsp_abs_4d(long); +#pragma intrinsic(dsp_abs_4d, opcode => 0x07, sub_opcode => 0x02 ) + +// User extension instruction - dsp_add_4d +extern long dsp_add_4d(long, long); +#pragma intrinsic(dsp_add_4d, opcode => 0x07, sub_opcode => 0x05 ) + +// User extension instruction - dsp_negate_4d +extern long dsp_negate_4d(long); +#pragma intrinsic(dsp_negate_4d, opcode => 0x07, sub_opcode => 0x11 ) + +// User extension instruction - dsp_shift_4d +extern long dsp_shift_4d(long, long); +#pragma intrinsic(dsp_shift_4d, opcode => 0x07, sub_opcode => 0x1A ) + +// User extension instruction - dsp_sub_4d +extern long dsp_sub_4d(long, long); +#pragma intrinsic(dsp_sub_4d, opcode => 0x07, sub_opcode => 0x08 ) + +// User extension instruction - mac32x16_fl +extern long mac32x16_fl(long, long); +#pragma intrinsic(mac32x16_fl, opcode => 0x07, sub_opcode => 0x39 , latency_cycles => 2) + +// User extension instruction - mac32x16_fl_f +extern long mac32x16_fl_f(long, long); +#pragma intrinsic(mac32x16_fl_f, opcode => 0x07, sub_opcode => 0x39, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - scgsin +extern long scgsin(long, long); +#pragma intrinsic(scgsin, opcode => 0x07, sub_opcode => 0x12 , latency_cycles => 2) + +// User extension instruction - dsubh22 +extern long dsubh22(long, long); +#pragma intrinsic(dsubh22, opcode => 0x06, sub_opcode => 0x13 , blocking_cycles => 5) + +// User extension instruction - dsubh22_f +extern long dsubh22_f(long, long); +#pragma intrinsic(dsubh22_f, opcode => 0x06, sub_opcode => 0x13, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - macrdwe +extern long macrdwe(long, long); +#pragma intrinsic(macrdwe, opcode => 0x07, sub_opcode => 0x17 , latency_cycles => 2) + +// User extension instruction - macrdwe_f +extern long macrdwe_f(long, long); +#pragma intrinsic(macrdwe_f, opcode => 0x07, sub_opcode => 0x17, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - msub32x16_fl +extern long msub32x16_fl(long, long); +#pragma intrinsic(msub32x16_fl, opcode => 0x07, sub_opcode => 0x3a , latency_cycles => 2) + +// User extension instruction - msub32x16_fl_f +extern long msub32x16_fl_f(long, long); +#pragma intrinsic(msub32x16_fl_f, opcode => 0x07, sub_opcode => 0x3a, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - scgcos +extern long scgcos(long, long); +#pragma intrinsic(scgcos, opcode => 0x07, sub_opcode => 0x13 , latency_cycles => 2) + +// User extension instruction - drsubh11 +extern long drsubh11(long, long); +#pragma intrinsic(drsubh11, opcode => 0x06, sub_opcode => 0x14 , blocking_cycles => 5) + +// User extension instruction - drsubh11_f +extern long drsubh11_f(long, long); +#pragma intrinsic(drsubh11_f, opcode => 0x06, sub_opcode => 0x14, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - mulcj +extern long mulcj(long, long); +#pragma intrinsic(mulcj, opcode => 0x07, sub_opcode => 0x02 , latency_cycles => 2) + +// User extension instruction - mulcj_f +extern long mulcj_f(long, long); +#pragma intrinsic(mulcj_f, opcode => 0x07, sub_opcode => 0x02, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mpy32x16_fh +extern long mpy32x16_fh(long, long); +#pragma intrinsic(mpy32x16_fh, opcode => 0x07, sub_opcode => 0x34 , latency_cycles => 2) + +// User extension instruction - mpy32x16_fh_f +extern long mpy32x16_fh_f(long, long); +#pragma intrinsic(mpy32x16_fh_f, opcode => 0x07, sub_opcode => 0x34, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - scgexpjrst +extern void scgexpjrst(); +#pragma intrinsic(scgexpjrst, opcode => 0x07, sub_opcode => 0x1c, assume_volatile => 1) + +// User extension instruction - drsubh12 +extern long drsubh12(long, long); +#pragma intrinsic(drsubh12, opcode => 0x06, sub_opcode => 0x15 , blocking_cycles => 5) + +// User extension instruction - drsubh12_f +extern long drsubh12_f(long, long); +#pragma intrinsic(drsubh12_f, opcode => 0x06, sub_opcode => 0x15, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - muldwz +extern long muldwz(long, long); +#pragma intrinsic(muldwz, opcode => 0x07, sub_opcode => 0x25 , latency_cycles => 2) + +// User extension instruction - muldwz_f +extern long muldwz_f(long, long); +#pragma intrinsic(muldwz_f, opcode => 0x07, sub_opcode => 0x25, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mac32x16_fh +extern long mac32x16_fh(long, long); +#pragma intrinsic(mac32x16_fh, opcode => 0x07, sub_opcode => 0x3c , latency_cycles => 2) + +// User extension instruction - mac32x16_fh_f +extern long mac32x16_fh_f(long, long); +#pragma intrinsic(mac32x16_fh_f, opcode => 0x07, sub_opcode => 0x3c, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - drsubh21 +extern long drsubh21(long, long); +#pragma intrinsic(drsubh21, opcode => 0x06, sub_opcode => 0x16 , blocking_cycles => 5) + +// User extension instruction - drsubh21_f +extern long drsubh21_f(long, long); +#pragma intrinsic(drsubh21_f, opcode => 0x06, sub_opcode => 0x16, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - mulrdwz +extern long mulrdwz(long, long); +#pragma intrinsic(mulrdwz, opcode => 0x07, sub_opcode => 0x26 , latency_cycles => 2) + +// User extension instruction - mulrdwz_f +extern long mulrdwz_f(long, long); +#pragma intrinsic(mulrdwz_f, opcode => 0x07, sub_opcode => 0x26, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - msub32x16_fh +extern long msub32x16_fh(long, long); +#pragma intrinsic(msub32x16_fh, opcode => 0x07, sub_opcode => 0x3d , latency_cycles => 2) + +// User extension instruction - msub32x16_fh_f +extern long msub32x16_fh_f(long, long); +#pragma intrinsic(msub32x16_fh_f, opcode => 0x07, sub_opcode => 0x3d, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - drsubh22 +extern long drsubh22(long, long); +#pragma intrinsic(drsubh22, opcode => 0x06, sub_opcode => 0x17 , blocking_cycles => 5) + +// User extension instruction - drsubh22_f +extern long drsubh22_f(long, long); +#pragma intrinsic(drsubh22_f, opcode => 0x06, sub_opcode => 0x17, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - macdwz +extern long macdwz(long, long); +#pragma intrinsic(macdwz, opcode => 0x07, sub_opcode => 0x28 , latency_cycles => 2) + +// User extension instruction - macdwz_f +extern long macdwz_f(long, long); +#pragma intrinsic(macdwz_f, opcode => 0x07, sub_opcode => 0x28, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - msub16x16_ll +extern long msub16x16_ll(long, long); +#pragma intrinsic(msub16x16_ll, opcode => 0x07, sub_opcode => 0x3b , latency_cycles => 2) + +// User extension instruction - msub16x16_ll_f +extern long msub16x16_ll_f(long, long); +#pragma intrinsic(msub16x16_ll_f, opcode => 0x07, sub_opcode => 0x3b, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dexcl1 +extern long dexcl1(long, long); +#pragma intrinsic(dexcl1, opcode => 0x06, sub_opcode => 0x18 ) + +// User extension instruction - dexcl1_f +extern long dexcl1_f(long, long); +#pragma intrinsic(dexcl1_f, opcode => 0x06, sub_opcode => 0x18, set_flags => 1, flags => "zncv" ) + +// User extension instruction - macrdwz +extern long macrdwz(long, long); +#pragma intrinsic(macrdwz, opcode => 0x07, sub_opcode => 0x29 , latency_cycles => 2) + +// User extension instruction - macrdwz_f +extern long macrdwz_f(long, long); +#pragma intrinsic(macrdwz_f, opcode => 0x07, sub_opcode => 0x29, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mpy16x16_hl +extern long mpy16x16_hl(long, long); +#pragma intrinsic(mpy16x16_hl, opcode => 0x07, sub_opcode => 0x31 , latency_cycles => 2) + +// User extension instruction - mpy16x16_hl_f +extern long mpy16x16_hl_f(long, long); +#pragma intrinsic(mpy16x16_hl_f, opcode => 0x07, sub_opcode => 0x31, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dexcl2 +extern long dexcl2(long, long); +#pragma intrinsic(dexcl2, opcode => 0x06, sub_opcode => 0x19 ) + +// User extension instruction - dexcl2_f +extern long dexcl2_f(long, long); +#pragma intrinsic(dexcl2_f, opcode => 0x06, sub_opcode => 0x19, set_flags => 1, flags => "zncv" ) + +// User extension instruction - mulrcj +extern long mulrcj(long, long); +#pragma intrinsic(mulrcj, opcode => 0x07, sub_opcode => 0x20 , latency_cycles => 2) + +// User extension instruction - mulrcj_f +extern long mulrcj_f(long, long); +#pragma intrinsic(mulrcj_f, opcode => 0x07, sub_opcode => 0x20, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mac16x16_hl +extern long mac16x16_hl(long, long); +#pragma intrinsic(mac16x16_hl, opcode => 0x07, sub_opcode => 0x32 , latency_cycles => 2) + +// User extension instruction - mac16x16_hl_f +extern long mac16x16_hl_f(long, long); +#pragma intrinsic(mac16x16_hl_f, opcode => 0x07, sub_opcode => 0x32, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dmulh21 +extern long dmulh21(long, long); +#pragma intrinsic(dmulh21, opcode => 0x06, sub_opcode => 0x0a , blocking_cycles => 7) + +// User extension instruction - dmulh21_f +extern long dmulh21_f(long, long); +#pragma intrinsic(dmulh21_f, opcode => 0x06, sub_opcode => 0x0a, set_flags => 1, flags => "zncv" , blocking_cycles => 7) + +// User extension instruction - mulr2w +extern long mulr2w(long, long); +#pragma intrinsic(mulr2w, opcode => 0x07, sub_opcode => 0x22 , latency_cycles => 2) + +// User extension instruction - mulr2w_f +extern long mulr2w_f(long, long); +#pragma intrinsic(mulr2w_f, opcode => 0x07, sub_opcode => 0x22, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - msub16x16_hl +extern long msub16x16_hl(long, long); +#pragma intrinsic(msub16x16_hl, opcode => 0x07, sub_opcode => 0x35 , latency_cycles => 2) + +// User extension instruction - msub16x16_hl_f +extern long msub16x16_hl_f(long, long); +#pragma intrinsic(msub16x16_hl_f, opcode => 0x07, sub_opcode => 0x35, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dmulh22 +extern long dmulh22(long, long); +#pragma intrinsic(dmulh22, opcode => 0x06, sub_opcode => 0x0b , blocking_cycles => 7) + +// User extension instruction - dmulh22_f +extern long dmulh22_f(long, long); +#pragma intrinsic(dmulh22_f, opcode => 0x06, sub_opcode => 0x0b, set_flags => 1, flags => "zncv" , blocking_cycles => 7) + +// User extension instruction - mul2w +extern long mul2w(long, long); +#pragma intrinsic(mul2w, opcode => 0x07, sub_opcode => 0x21 , latency_cycles => 2) + +// User extension instruction - mul2w_f +extern long mul2w_f(long, long); +#pragma intrinsic(mul2w_f, opcode => 0x07, sub_opcode => 0x21, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mpy16x16_hh +extern long mpy16x16_hh(long, long); +#pragma intrinsic(mpy16x16_hh, opcode => 0x07, sub_opcode => 0x30 , latency_cycles => 2) + +// User extension instruction - mpy16x16_hh_f +extern long mpy16x16_hh_f(long, long); +#pragma intrinsic(mpy16x16_hh_f, opcode => 0x07, sub_opcode => 0x30, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - daddh11 +extern long daddh11(long, long); +#pragma intrinsic(daddh11, opcode => 0x06, sub_opcode => 0x0c , blocking_cycles => 5) + +// User extension instruction - daddh11_f +extern long daddh11_f(long, long); +#pragma intrinsic(daddh11_f, opcode => 0x06, sub_opcode => 0x0c, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - maccj +extern long maccj(long, long); +#pragma intrinsic(maccj, opcode => 0x07, sub_opcode => 0x0a , latency_cycles => 2) + +// User extension instruction - maccj_f +extern long maccj_f(long, long); +#pragma intrinsic(maccj_f, opcode => 0x07, sub_opcode => 0x0a, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mac16x16_hh +extern long mac16x16_hh(long, long); +#pragma intrinsic(mac16x16_hh, opcode => 0x07, sub_opcode => 0x36 , latency_cycles => 2) + +// User extension instruction - mac16x16_hh_f +extern long mac16x16_hh_f(long, long); +#pragma intrinsic(mac16x16_hh_f, opcode => 0x07, sub_opcode => 0x36, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - daddh12 +extern long daddh12(long, long); +#pragma intrinsic(daddh12, opcode => 0x06, sub_opcode => 0x0d , blocking_cycles => 5) + +// User extension instruction - daddh12_f +extern long daddh12_f(long, long); +#pragma intrinsic(daddh12_f, opcode => 0x06, sub_opcode => 0x0d, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - muldwo +extern long muldwo(long, long); +#pragma intrinsic(muldwo, opcode => 0x07, sub_opcode => 0x23 , latency_cycles => 2) + +// User extension instruction - muldwo_f +extern long muldwo_f(long, long); +#pragma intrinsic(muldwo_f, opcode => 0x07, sub_opcode => 0x23, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - msub16x16_hh +extern long msub16x16_hh(long, long); +#pragma intrinsic(msub16x16_hh, opcode => 0x07, sub_opcode => 0x38 , latency_cycles => 2) + +// User extension instruction - msub16x16_hh_f +extern long msub16x16_hh_f(long, long); +#pragma intrinsic(msub16x16_hh_f, opcode => 0x07, sub_opcode => 0x38, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - daddh21 +extern long daddh21(long, long); +#pragma intrinsic(daddh21, opcode => 0x06, sub_opcode => 0x0e , blocking_cycles => 5) + +// User extension instruction - daddh21_f +extern long daddh21_f(long, long); +#pragma intrinsic(daddh21_f, opcode => 0x06, sub_opcode => 0x0e, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - mulrdwo +extern long mulrdwo(long, long); +#pragma intrinsic(mulrdwo, opcode => 0x07, sub_opcode => 0x27 , latency_cycles => 2) + +// User extension instruction - mulrdwo_f +extern long mulrdwo_f(long, long); +#pragma intrinsic(mulrdwo_f, opcode => 0x07, sub_opcode => 0x27, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mpy32x16_fl +extern long mpy32x16_fl(long, long); +#pragma intrinsic(mpy32x16_fl, opcode => 0x07, sub_opcode => 0x33 , latency_cycles => 2) + +// User extension instruction - mpy32x16_fl_f +extern long mpy32x16_fl_f(long, long); +#pragma intrinsic(mpy32x16_fl_f, opcode => 0x07, sub_opcode => 0x33, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - daddh22 +extern long daddh22(long, long); +#pragma intrinsic(daddh22, opcode => 0x06, sub_opcode => 0x0f , blocking_cycles => 5) + +// User extension instruction - daddh22_f +extern long daddh22_f(long, long); +#pragma intrinsic(daddh22_f, opcode => 0x06, sub_opcode => 0x0f, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - maccc +extern long maccc(long, long); +#pragma intrinsic(maccc, opcode => 0x07, sub_opcode => 0x24 , latency_cycles => 2) + +// User extension instruction - maccc_f +extern long maccc_f(long, long); +#pragma intrinsic(maccc_f, opcode => 0x07, sub_opcode => 0x24, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dsubh11 +extern long dsubh11(long, long); +#pragma intrinsic(dsubh11, opcode => 0x06, sub_opcode => 0x10 , blocking_cycles => 5) + +// User extension instruction - dsubh11_f +extern long dsubh11_f(long, long); +#pragma intrinsic(dsubh11_f, opcode => 0x06, sub_opcode => 0x10, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - macrcc +extern long macrcc(long, long); +#pragma intrinsic(macrcc, opcode => 0x07, sub_opcode => 0x09 , latency_cycles => 2) + +// User extension instruction - macrcc_f +extern long macrcc_f(long, long); +#pragma intrinsic(macrcc_f, opcode => 0x07, sub_opcode => 0x09, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - dsubh12 +extern long dsubh12(long, long); +#pragma intrinsic(dsubh12, opcode => 0x06, sub_opcode => 0x11 , blocking_cycles => 5) + +// User extension instruction - dsubh12_f +extern long dsubh12_f(long, long); +#pragma intrinsic(dsubh12_f, opcode => 0x06, sub_opcode => 0x11, set_flags => 1, flags => "zncv" , blocking_cycles => 5) + +// User extension instruction - macrcj +extern long macrcj(long, long); +#pragma intrinsic(macrcj, opcode => 0x07, sub_opcode => 0x0b , latency_cycles => 2) + +// User extension instruction - macrcj_f +extern long macrcj_f(long, long); +#pragma intrinsic(macrcj_f, opcode => 0x07, sub_opcode => 0x0b, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mac2w +extern long mac2w(long, long); +#pragma intrinsic(mac2w, opcode => 0x07, sub_opcode => 0x0c , latency_cycles => 2) + +// User extension instruction - mac2w_f +extern long mac2w_f(long, long); +#pragma intrinsic(mac2w_f, opcode => 0x07, sub_opcode => 0x0c, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - macr2w +extern long macr2w(long, long); +#pragma intrinsic(macr2w, opcode => 0x07, sub_opcode => 0x0d , latency_cycles => 2) + +// User extension instruction - macr2w_f +extern long macr2w_f(long, long); +#pragma intrinsic(macr2w_f, opcode => 0x07, sub_opcode => 0x0d, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - macdwo +extern long macdwo(long, long); +#pragma intrinsic(macdwo, opcode => 0x07, sub_opcode => 0x0e , latency_cycles => 2) + +// User extension instruction - macdwo_f +extern long macdwo_f(long, long); +#pragma intrinsic(macdwo_f, opcode => 0x07, sub_opcode => 0x0e, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - macrdwo +extern long macrdwo(long, long); +#pragma intrinsic(macrdwo, opcode => 0x07, sub_opcode => 0x0f , latency_cycles => 2) + +// User extension instruction - macrdwo_f +extern long macrdwo_f(long, long); +#pragma intrinsic(macrdwo_f, opcode => 0x07, sub_opcode => 0x0f, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - muldwe +extern long muldwe(long, long); +#pragma intrinsic(muldwe, opcode => 0x07, sub_opcode => 0x14 , latency_cycles => 2) + +// User extension instruction - muldwe_f +extern long muldwe_f(long, long); +#pragma intrinsic(muldwe_f, opcode => 0x07, sub_opcode => 0x14, set_flags => 1, flags => "zncv" , latency_cycles => 2) + +// User extension instruction - mulrdwe +extern long mulrdwe(long, long); +#pragma intrinsic(mulrdwe, opcode => 0x07, sub_opcode => 0x15 , latency_cycles => 2) + +// User extension instruction - mulrdwe_f +extern long mulrdwe_f(long, long); +#pragma intrinsic(mulrdwe_f, opcode => 0x07, sub_opcode => 0x15, set_flags => 1, flags => "zncv" , latency_cycles => 2) +#endif + +// User extension aux register - dpfp_build +#define AR_DPFP_BUILD 0x6c + +// User extension aux register - fp_build +#define AR_FP_BUILD 0x6b + +// User extension aux register - aux_cmac_accum0 +#define AR_AUX_CMAC_ACCUM0 0xB0 + +// User extension aux register - dsp_fp_cmp_min +#define AR_DSP_FP_CMP_MIN 0xBE + +// User extension aux register - dsp_mac_msbout +#define AR_DSP_MAC_MSBOUT 0x80000000 + +// User extension aux register - io_adc0_set +#define AR_IO_ADC0_SET 0x80015000 + +// User extension aux register - io_creg_mst0_ctrl +#define AR_IO_CREG_MST0_CTRL 0x80018000 + +// User extension aux register - io_creg_slv0_obsr +#define AR_IO_CREG_SLV0_OBSR 0x80018080 + +// User extension aux register - io_creg_slv1_obsr +#define AR_IO_CREG_SLV1_OBSR 0x80018180 + +// User extension aux register - io_gpio_8b0_swporta_dr +#define AR_IO_GPIO_8B0_SWPORTA_DR 0x80017800 + +// User extension aux register - io_gpio_8b1_swporta_dr +#define AR_IO_GPIO_8B1_SWPORTA_DR 0x80017900 + +// User extension aux register - io_i2c_mst0_con +#define AR_IO_I2C_MST0_CON 0x80012000 + +// User extension aux register - io_i2c_mst1_con +#define AR_IO_I2C_MST1_CON 0x80012100 + +// User extension aux register - mul32x16_accum_l +#define AR_MUL32X16_ACCUM_L 0x110 + +// User extension aux register - aux_scgen_acc1 +#define AR_AUX_SCGEN_ACC1 0xd9 + +// User extension aux register - aux_dpfp1l +#define AR_AUX_DPFP1L 0x301 + +// User extension aux register - fp_status +#define AR_FP_STATUS 0x300 + +// User extension aux register - aux_cmac_accum1 +#define AR_AUX_CMAC_ACCUM1 0xB1 + +// User extension aux register - dsp_fp_cmp_max +#define AR_DSP_FP_CMP_MAX 0xBF + +// User extension aux register - dsp_mac_lsbout +#define AR_DSP_MAC_LSBOUT 0x80000001 + +// User extension aux register - io_adc0_divseqstat +#define AR_IO_ADC0_DIVSEQSTAT 0x80015001 + +// User extension aux register - io_gpio_8b0_swporta_ddr +#define AR_IO_GPIO_8B0_SWPORTA_DDR 0x80017801 + +// User extension aux register - io_gpio_8b1_swporta_ddr +#define AR_IO_GPIO_8B1_SWPORTA_DDR 0x80017901 + +// User extension aux register - io_spi_mst0_ctrl +#define AR_IO_SPI_MST0_CTRL 0x80010000 + +// User extension aux register - io_spi_mst1_ctrl +#define AR_IO_SPI_MST1_CTRL 0x80010100 + +// User extension aux register - mul32x16_accum_h +#define AR_MUL32X16_ACCUM_H 0x111 + +// User extension aux register - aux_dpfp1h +#define AR_AUX_DPFP1H 0x302 + +// User extension aux register - aux_cmac_accum2 +#define AR_AUX_CMAC_ACCUM2 0xB2 + +// User extension aux register - io_adc0_seq +#define AR_IO_ADC0_SEQ 0x80015002 + +// User extension aux register - io_i2c_mst0_data_cmd +#define AR_IO_I2C_MST0_DATA_CMD 0x80012001 + +// User extension aux register - io_i2c_mst1_data_cmd +#define AR_IO_I2C_MST1_DATA_CMD 0x80012101 + +// User extension aux register - mul32x16_ctrl +#define AR_MUL32X16_CTRL 0x112 + +// User extension aux register - aux_dpfp2l +#define AR_AUX_DPFP2L 0x303 + +// User extension aux register - aux_cmac_acc_shft +#define AR_AUX_CMAC_ACC_SHFT 0xB3 + +// User extension aux register - io_adc0_ctrl +#define AR_IO_ADC0_CTRL 0x80015003 + +// User extension aux register - io_gpio_8b0_inten +#define AR_IO_GPIO_8B0_INTEN 0x80017803 + +// User extension aux register - io_gpio_8b1_inten +#define AR_IO_GPIO_8B1_INTEN 0x80017903 + +// User extension aux register - aux_dpfp2h +#define AR_AUX_DPFP2H 0x304 + +// User extension aux register - aux_cmac_acc1 +#define AR_AUX_CMAC_ACC1 0xB4 + +// User extension aux register - io_adc0_intstat +#define AR_IO_ADC0_INTSTAT 0x80015004 + +// User extension aux register - io_gpio_8b0_inttype_level +#define AR_IO_GPIO_8B0_INTTYPE_LEVEL 0x80017805 + +// User extension aux register - io_gpio_8b1_inttype_level +#define AR_IO_GPIO_8B1_INTTYPE_LEVEL 0x80017905 + +// User extension aux register - io_i2c_mst0_ss_scl_cnt +#define AR_IO_I2C_MST0_SS_SCL_CNT 0x80012002 + +// User extension aux register - io_i2c_mst1_ss_scl_cnt +#define AR_IO_I2C_MST1_SS_SCL_CNT 0x80012102 + +// User extension aux register - dpfp_status +#define AR_DPFP_STATUS 0x305 + +// User extension aux register - aux_cmac_acc2 +#define AR_AUX_CMAC_ACC2 0xB5 + +// User extension aux register - io_adc0_sample +#define AR_IO_ADC0_SAMPLE 0x80015005 + +// User extension aux register - io_gpio_8b0_int_polarity +#define AR_IO_GPIO_8B0_INT_POLARITY 0x80017806 + +// User extension aux register - io_gpio_8b1_int_polarity +#define AR_IO_GPIO_8B1_INT_POLARITY 0x80017906 + +// User extension aux register - aux_cmac_status_mode +#define AR_AUX_CMAC_STATUS_MODE 0xB6 + +// User extension aux register - io_gpio_8b0_intstatus +#define AR_IO_GPIO_8B0_INTSTATUS 0x80017807 + +// User extension aux register - io_gpio_8b1_intstatus +#define AR_IO_GPIO_8B1_INTSTATUS 0x80017907 + +// User extension aux register - io_i2c_mst0_fs_scl_cnt +#define AR_IO_I2C_MST0_FS_SCL_CNT 0x80012004 + +// User extension aux register - io_i2c_mst1_fs_scl_cnt +#define AR_IO_I2C_MST1_FS_SCL_CNT 0x80012104 + +// User extension aux register - aux_cmac_src_shift +#define AR_AUX_CMAC_SRC_SHIFT 0xB7 + +// User extension aux register - io_gpio_8b0_debounce +#define AR_IO_GPIO_8B0_DEBOUNCE 0x80017808 + +// User extension aux register - io_gpio_8b1_debounce +#define AR_IO_GPIO_8B1_DEBOUNCE 0x80017908 + +// User extension aux register - io_i2c_mst0_intr_stat +#define AR_IO_I2C_MST0_INTR_STAT 0x80012006 + +// User extension aux register - io_i2c_mst1_intr_stat +#define AR_IO_I2C_MST1_INTR_STAT 0x80012106 + +// User extension aux register - io_gpio_8b0_porta_eoi +#define AR_IO_GPIO_8B0_PORTA_EOI 0x80017809 + +// User extension aux register - io_gpio_8b1_porta_eoi +#define AR_IO_GPIO_8B1_PORTA_EOI 0x80017909 + +// User extension aux register - io_i2c_mst0_intr_mask +#define AR_IO_I2C_MST0_INTR_MASK 0x80012007 + +// User extension aux register - io_i2c_mst1_intr_mask +#define AR_IO_I2C_MST1_INTR_MASK 0x80012107 + +// User extension aux register - io_gpio_8b0_ext_porta +#define AR_IO_GPIO_8B0_EXT_PORTA 0x8001780A + +// User extension aux register - io_gpio_8b1_ext_porta +#define AR_IO_GPIO_8B1_EXT_PORTA 0x8001790a + +// User extension aux register - io_i2c_mst0_tl +#define AR_IO_I2C_MST0_TL 0x80012008 + +// User extension aux register - io_i2c_mst1_tl +#define AR_IO_I2C_MST1_TL 0x80012108 + +// User extension aux register - io_gpio_8b0_ls_sync +#define AR_IO_GPIO_8B0_LS_SYNC 0x8001780B + +// User extension aux register - io_gpio_8b1_ls_sync +#define AR_IO_GPIO_8B1_LS_SYNC 0x8001790b + +// User extension aux register - io_gpio_8b0_intmask +#define AR_IO_GPIO_8B0_INTMASK 0x80017804 + +// User extension aux register - io_gpio_8b1_intmask +#define AR_IO_GPIO_8B1_INTMASK 0x80017904 + +// User extension aux register - io_i2c_mst0_intr_clr +#define AR_IO_I2C_MST0_INTR_CLR 0x8001200A + +// User extension aux register - io_i2c_mst1_intr_clr +#define AR_IO_I2C_MST1_INTR_CLR 0x8001210a + +// User extension aux register - io_spi_mst0_spien +#define AR_IO_SPI_MST0_SPIEN 0x80010002 + +// User extension aux register - io_spi_mst1_spien +#define AR_IO_SPI_MST1_SPIEN 0x80010102 + +// User extension aux register - io_i2c_mst0_status +#define AR_IO_I2C_MST0_STATUS 0x8001200B + +// User extension aux register - io_i2c_mst1_status +#define AR_IO_I2C_MST1_STATUS 0x8001210b + +// User extension aux register - io_i2c_mst0_txflr +#define AR_IO_I2C_MST0_TXFLR 0x8001200C + +// User extension aux register - io_i2c_mst1_txflr +#define AR_IO_I2C_MST1_TXFLR 0x8001210c + +// User extension aux register - io_i2c_mst0_rxflr +#define AR_IO_I2C_MST0_RXFLR 0x8001200D + +// User extension aux register - io_i2c_mst1_rxflr +#define AR_IO_I2C_MST1_RXFLR 0x8001210d + +// User extension aux register - io_i2c_mst0_sda_config +#define AR_IO_I2C_MST0_SDA_CONFIG 0x8001200E + +// User extension aux register - io_i2c_mst1_sda_config +#define AR_IO_I2C_MST1_SDA_CONFIG 0x8001210e + +// User extension aux register - io_i2c_mst0_tx_abrt_source +#define AR_IO_I2C_MST0_TX_ABRT_SOURCE 0x8001200F + +// User extension aux register - io_i2c_mst1_tx_abrt_source +#define AR_IO_I2C_MST1_TX_ABRT_SOURCE 0x8001210f + +// User extension aux register - io_spi_mst0_timing +#define AR_IO_SPI_MST0_TIMING 0x80010004 + +// User extension aux register - io_spi_mst1_timing +#define AR_IO_SPI_MST1_TIMING 0x80010104 + +// User extension aux register - io_i2c_mst0_enable_status +#define AR_IO_I2C_MST0_ENABLE_STATUS 0x80012011 + +// User extension aux register - io_i2c_mst1_enable_status +#define AR_IO_I2C_MST1_ENABLE_STATUS 0x80012111 + +// User extension aux register - io_spi_mst0_ftlr +#define AR_IO_SPI_MST0_FTLR 0x80010005 + +// User extension aux register - io_spi_mst1_ftlr +#define AR_IO_SPI_MST1_FTLR 0x80010105 + +// User extension aux register - io_spi_mst0_txflr +#define AR_IO_SPI_MST0_TXFLR 0x80010007 + +// User extension aux register - io_spi_mst1_txflr +#define AR_IO_SPI_MST1_TXFLR 0x80010107 + +// User extension aux register - io_spi_mst0_rxflr +#define AR_IO_SPI_MST0_RXFLR 0x80010008 + +// User extension aux register - io_spi_mst1_rxflr +#define AR_IO_SPI_MST1_RXFLR 0x80010108 + +// User extension aux register - io_spi_mst0_sr +#define AR_IO_SPI_MST0_SR 0x80010009 + +// User extension aux register - io_spi_mst1_sr +#define AR_IO_SPI_MST1_SR 0x80010109 + +// User extension aux register - io_spi_mst0_intr_stat +#define AR_IO_SPI_MST0_INTR_STAT 0x8001000A + +// User extension aux register - io_spi_mst1_intr_stat +#define AR_IO_SPI_MST1_INTR_STAT 0x8001010a + +// User extension aux register - io_spi_mst0_intr_mask +#define AR_IO_SPI_MST0_INTR_MASK 0x8001000B + +// User extension aux register - io_spi_mst1_intr_mask +#define AR_IO_SPI_MST1_INTR_MASK 0x8001010b + +// User extension aux register - io_spi_mst0_clr_intr +#define AR_IO_SPI_MST0_CLR_INTR 0x8001000C + +// User extension aux register - io_spi_mst1_clr_intr +#define AR_IO_SPI_MST1_CLR_INTR 0x8001010c + +// User extension aux register - io_spi_mst0_dr +#define AR_IO_SPI_MST0_DR 0x8001000D + +// User extension aux register - io_spi_mst1_dr +#define AR_IO_SPI_MST1_DR 0x8001010d + +#ifndef __GNUC__ +// User extension condition code cmac_ps +#pragma condition(20, name=>"cmac_ps") + +// User extension condition code cmac_psc +#pragma condition(21, name=>"cmac_psc") +#endif + +#include "compiler.h" + +#endif + + diff --git a/system/libarc32_edu/drivers/gpio.h b/system/libarc32_edu/drivers/gpio.h new file mode 100644 index 00000000..f025e490 --- /dev/null +++ b/system/libarc32_edu/drivers/gpio.h @@ -0,0 +1,102 @@ +/** INTEL CONFIDENTIAL Copyright 2014-2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef GPIO_IFACE_H_ +#define GPIO_IFACE_H_ + +#include "data_type.h" + +typedef void (*gpio_callback_fn)( uint32_t , void*); + +/*! + * GPIO types + */ +typedef enum { + GPIO_INPUT, /*!< Configure GPIO pin as input */ + GPIO_OUTPUT, /*!< Configure GPIO pin as output */ + GPIO_INTERRUPT /*!< Configure GPIO pin as interrupt */ +} GPIO_TYPE; + +/*! + * Interrupt types + */ +typedef enum { + LEVEL, /*!< Configure an interrupt triggered on level */ + EDGE, /*!< Configure an interrupt triggered on single edge */ + DOUBLE_EDGE /*!< Configure an interrupt triggered on both rising and falling edges */ +} INT_TYPE; + +/*! + * Polarity configuration for interrupts + */ +typedef enum { + ACTIVE_LOW, /*!< Configure an interrupt on low level or falling edge */ + ACTIVE_HIGH /*!< Configure an interrupt on high level or rising edge */ +} INT_POLARITY; + +/*! + * Debounce configuration for interrupts + */ +typedef enum { + DEBOUNCE_OFF, /*!< Disable debounce for interrupt */ + DEBOUNCE_ON /*!< Enable debounce for interrupt */ +} INT_DEBOUNCE; + +/*! + * ls_sync configuration for interrupts + */ +typedef enum { + LS_SYNC_OFF, /*!< Disable ls sync for interrupt */ + LS_SYNC_ON /*!< Enable ls sync for interrupt */ +} INT_LS_SYNC; + +/*! + * GPIO configuration structure + */ +typedef struct gpio_cfg_data { + GPIO_TYPE gpio_type; /*!< GPIO type */ + INT_TYPE int_type; /*!< GPIO interrupt type */ + INT_POLARITY int_polarity; /*!< GPIO polarity configuration */ + INT_DEBOUNCE int_debounce; /*!< GPIO debounce configuration */ + INT_LS_SYNC int_ls_sync; /*!< GPIO ls sync configuration */ + gpio_callback_fn gpio_cb; /*!< Callback function called when an interrupt is triggered on this pin */ + void *gpio_cb_arg; /*!< Data passed as an argument for the callback function */ +} gpio_cfg_data_t; + +/*! + * GPIO port configuration structure + */ +typedef struct gpio_port_cfg_data { + uint32_t gpio_type; /*!< Set port type (0=INPUT, 1=OUTPUT) */ + uint32_t is_interrupt; /*!< Enable interrupt on GPIO (0=OFF, 1=ON) */ + uint32_t int_type; /*!< Sets interrupt type (0=LEVEL, 1=EDGE) */ + uint32_t int_bothedge; /*!< Enable interrupt on both rising and falling edges (0=OFF, 1=ON) */ + uint32_t int_polarity; /*!< GPIO polarity configuration (0=LOW, 1=HIGH) */ + uint32_t int_debounce; /*!< GPIO debounce configuration (0=OFF, 1=ON) */ + uint32_t int_ls_sync; /*!< GPIO ls sync configuration (0=OFF, 1=ON) */ + gpio_callback_fn gpio_cb[32]; /*!< Callback function called when an interrupt is triggered on this pin */ + void *gpio_cb_arg[32]; /*!< Data passed as an argument for the callback function */ +} gpio_port_cfg_data_t; + +#endif /* GPIO_IFACE_H_ */ diff --git a/system/libarc32_edu/drivers/i2c_priv.h b/system/libarc32_edu/drivers/i2c_priv.h new file mode 100644 index 00000000..5c2e7b49 --- /dev/null +++ b/system/libarc32_edu/drivers/i2c_priv.h @@ -0,0 +1,175 @@ +/* +* +* CONFIDENTIAL AND PROPRIETARY INFORMATION +* +* Copyright (c) 2013 Synopsys, Inc. All rights reserved. +* This software and documentation contain confidential and +* proprietary information that is the property of +* Synopsys, Inc. The software and documentation are +* furnished under a license agreement and may be used +* or copied only in accordance with the terms of the license +* agreement. No part of the software and documentation +* may be reproduced, transmitted, or translated, in any +* form or by any means, electronic, mechanical, manual, +* optical, or otherwise, without prior written permission +* of Synopsys, Inc., or as expressly provided by the license agreement. +* Reverse engineering is prohibited, and reproduction, +* disclosure or use without specific written authorization +* of Synopsys Inc. is strictly forbidden. +*/ + + +#ifndef I2C_PRIV_H_ +#define I2C_PRIV_H_ +#include "eiaextensions.h" + +/* EIA I2C device registers */ +#define I2C_CON (0x00) // i2c control +#define I2C_DATA_CMD (0x01) // i2c Rx/Tx Data Buffer and Command +#define I2C_SS_SCL_CNT (0x02) // Standard Speed i2c SCL High/Low Counts */ +#define I2C_FS_SCL_CNT (0x04) // Fast Speed i2c SCL Low High/Low Counts */ +#define I2C_INTR_STAT (0x06) // i2c Interrupt Status */ +#define I2C_INTR_MASK (0x07) // i2c Interrupt Mask */ +#define I2C_TL (0x08) // i2c Tx/Rx FIFO Thresholds */ +#define I2C_CLR_INTR (0x0a) // Clear combined and Individual Interrupts */ +#define I2C_STATUS (0x0b) // i2c Status */ +#define I2C_TXFLR (0x0c) // Transmit FIFO Level Register */ +#define I2C_RXFLR (0x0d) // Receive FIFO Level Register */ +#define I2C_SDA_CONFIG (0x0e) // SDA Hold/Setup Time Length Reg */ +#define I2C_TX_ABRT_SOURCE (0x0f) // i2c Transmit Abort Status Reg */ +#define I2C_ENABLE_STATUS (0x11) // Enable Status Register */ + + +/* Interrupt Register Fields */ +#define R_START_DETECTED (1 << 10) +#define R_STOP_DETECTED (1 << 9) +#define R_ACTIVITY (1 << 8) +#define R_RX_DONE (1 << 7) +#define R_TX_ABRT (1 << 6) +#define R_RD_REQ (1 << 5) +#define R_TX_EMPTY (1 << 4) +#define R_TX_OVER (1 << 3) +#define R_RX_FULL (1 << 2) +#define R_RX_OVER (1 << 1) +#define R_RX_UNDER (1 << 0) + + +/* I2C Status Register Fields. */ +#define I2C_STATUS_ACTIVITY (0x01) +#define I2C_STATUS_TFNF (0x02) /* (1 << 1) */ +#define I2C_STATUS_TFE (0x04) /* (1 << 2) */ +#define I2C_STATUS_RFNE (0x08) /* (1 << 3) */ +#define I2C_STATUS_RFF (0x10) /* (1 << 4) */ +#define I2C_STATUS_MASTER_ACT (0x20) /* (1 << 5) */ +#define I2C_STATUS_SLAVE_ACT (0x40) /* (1 << 6) */ + +/* I2C TX Abort Source Register Fields */ +#define I2C_ABRT_SLVFLUSH_TXFIFO (1 << 13) +#define I2C_TX_FLUSH_COUNT_POS 24 + +/* Other macros. */ +#define I2C_CLK_ENABLED (1 << 31) +#define ENABLE_I2C (1) +#define DISABLE_I2C (0) +#define I2C_RESTART_CMD (0x400) +#define I2C_STOP_CMD (0x200) +#define I2C_READ_CMD (0x100) +#define I2C_PUSH_DATA (0xc0000000) +#define I2C_POP_DATA (0x80000000) +#define I2C_RESTART_EN (1 << 7) +#define I2C_SLAVE_DSB (1 << 8) +#define TX_ABORT (1 << 1) + +#define I2C_ENABLE_MASTER (1 << 0) +#define I2C_ENABLE_SLAVE (1 << 6) + +/* I2C default interrupt enable & disable macro's. */ +#define I2C_INT_ENB (R_TX_ABRT | R_RX_FULL | R_RX_OVER | R_STOP_DETECTED) +#define I2C_INT_DSB (0x00) + +/* I2C device state. */ +#define I2C_STATE_CLOSED (0) +#define I2C_STATE_READY (1) +#define I2C_STATE_RECEIVE (2) +#define I2C_STATE_TRANSMIT (3) +#define I2C_STATE_DISABLED (4) + +/* I2C working speeds. */ +#define STANDARD_SPEED (0x01) +#define FAST_SPEED (0x02) + +#ifndef __GNUC__ +typedef _Interrupt void (*I2C_ISR) (); +#else +typedef void (*I2C_ISR)(); +#endif +typedef void (*IO_CB_FUNC)(uint32_t); + +/* Private data structure maintained by the driver */ +typedef struct i2c_info { + uint32_t reg_base; // base address of device register set + uint8_t instID; + uint8_t state; + uint16_t fifo_depth; + /* Transmitted bytes. */ + uint32_t total_read_bytes; + uint32_t total_write_bytes; + uint32_t tx_len; + uint32_t rx_len; + uint32_t rx_tx_len; // tx_len + rx_len + uint8_t *i2c_write_buff; + uint8_t *i2c_read_buff; + + /* Callbacks */ + IO_CB_FUNC tx_cb; + IO_CB_FUNC rx_cb; + IO_CB_FUNC err_cb; + uint32_t cb_rx_data; + uint32_t cb_tx_data; + uint32_t cb_err_data; + /* Interrupt numbers and handlers */ + uint8_t vector_err; // ISR vector, error interrupt + uint8_t vector_rx_avail; // ISR vector, rx interrupt + uint8_t vector_tx_req; // ISR vector, tx interrupt + uint8_t vector_rd_req; // ISR vector, read request interrupt + uint8_t vector_stop_detected; // ISR vector, stop detect interrupt + I2C_ISR isr_err; // I2C device ISR, error interrupt + I2C_ISR isr_rx_avail; // I2C device ISR, rx interrupt + I2C_ISR isr_tx_req; // I2C device ISR, tx interrupt + I2C_ISR isr_rd_req; // I2C device ISR, read request interrupt + I2C_ISR isr_stop_detected; // I2C device ISR, stop detect interrupt + + /* status return code */ + uint32_t status_code; + /* SSS Interrupt Routing Mask Registers */ + uint32_t i2c_rx_avail_mask; + uint32_t i2c_tx_req_mask; + uint32_t i2c_err_mask; + uint32_t i2c_stop_detected_mask; + /* CREG Master clock gate bit location */ + uint8_t creg_i2c_clk_ctrl; +} i2c_info_t, *i2c_info_pt; + + +/* I2C software configs */ +#define I2C_ALLOW_RESTART (1) +#define I2C_TX_FIFO_THRESHOLD (0) +#define I2C_RX_FIFO_THRESHOLD (0) // Value 0 means 1 element in Rx FIFO triggers interrupt + +/* I2C IOCTLs default values */ +#define I2C_SPKLEN (0x05) +#define I2C_SETUP_TIME (0x64) +#define I2C_HOLD_TIME (0x01) +#define I2C_SPEED_MODE FAST_SPEED +#define I2C_SLAVE_ADDR (0x55) // Default for IO_I2C_SLAVE_SET_ADDR and IO_I2C_MASTER_SET_TARGET_ADDR +#define I2C_SS_SCL_HIGH_COUNT (0x0190) +#define I2C_SS_SCL_LOW_COUNT (0x01d6) +#define I2C_FS_SCL_HIGH_COUNT (0x003c) +#define I2C_FS_SCL_LOW_COUNT (0x0082) + +#define REG_WRITE( reg, x ) _sr( (unsigned)(x), (unsigned)(dev->reg_base + reg) ) +#define REG_READ( reg ) _lr( (unsigned)(dev->reg_base + reg) ) +#define REG_WRITE_BITS( reg, x, y, len, pos ) REG_WRITE( reg, ( (((x) & ~( (~(0xffffffff << len)) << pos )) \ + | (((y) << pos) & ( (~(0xffffffff << len)) << pos ))) )) + +#endif diff --git a/system/libarc32_edu/drivers/intel_qrk_pwm.c b/system/libarc32_edu/drivers/intel_qrk_pwm.c new file mode 100644 index 00000000..d0322c32 --- /dev/null +++ b/system/libarc32_edu/drivers/intel_qrk_pwm.c @@ -0,0 +1,404 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#include "intel_qrk_pwm.h" +#include "portable.h" +#include "scss_registers.h" + +#ifdef CONFIG_BOARD_ATLASPEAK_FPGA + /* Clock is 16Mzh */ + #define GRANULARITY_X_100 6250 +#else + /* Clock is 32 Mhz */ + #define GRANULARITY_X_100 3125 +#endif + +/* One nanosecond in hertz */ +#define NS_IN_HZ 1000000000 + +/* TODO: DB - 64Bit calculation not working, causes issues setting slow speeds/high timers*/ + +#ifdef __cplusplus + extern "C" { +#endif + +static uint32_t soc_pwm_ioread(uint8_t channel, uint32_t offset); +static void soc_pwm_iowrite(uint8_t channel, uint32_t offset, uint32_t val); +static void soc_pwm_mask_interrupt(uint8_t channel); +static void soc_pwm_unmask_interrupt(uint8_t channel); +static DRIVER_API_RC soc_pwm_check_config(struct soc_pwm_channel_config *config); + +boolean_t one_shot[QRK_PWM_NPWM]; +void (*callback_fn[QRK_PWM_NPWM]) (void); + +/*! \fn void soc_pwm_enable(void) +* +* \brief Function disable clock gating for the PWM device +*/ +/* @TODO: clock gating is not supported on FPGA - test on silicon when available */ +void soc_pwm_enable(void) +{ + MMIO_REG_VAL(QRK_CLKGATE_CTRL) |= QRK_CLKGATE_CTRL_PWM_ENABLE; +} + +/*! \fn void soc_pwm_disable(void) +* +* \brief Function to enable clock gating for the PWM device +*/ +void soc_pwm_disable(void) +{ + MMIO_REG_VAL(QRK_CLKGATE_CTRL) &= ~QRK_CLKGATE_CTRL_PWM_ENABLE; +} + + +/* + * The channel specific registers are grouped in sequential blocks of size + * 0x14. However, the 4 LCNT2 registers are grouped seperately. + * Therefore, the address calculation changes accordingly for LCNT2. + */ +static uint32_t soc_pwm_ioread(uint8_t channel, uint32_t offset) +{ + int regs_len = 0; + + if (QRK_PWM_N_LOAD_COUNT2 == offset) + { + regs_len = QRK_PWM_N_LCNT2_LEN; + } + + else + { + regs_len = QRK_PWM_N_REGS_LEN; + } + + return MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, ((channel * regs_len) + + offset)); +} + +/* + * The channel specific registers are grouped in 4 sequential blocks of size + * 0x14. However, the 4 LCNT2 registers are grouped seperately. + * Therefore, the address calculation changes accordingly for LCNT2. + */ +static void soc_pwm_iowrite(uint8_t channel, uint32_t offset, uint32_t val) +{ + int regs_len = 0; + + if (QRK_PWM_N_LOAD_COUNT2 == offset) + { + regs_len = QRK_PWM_N_LCNT2_LEN; + } + + else + { + regs_len = QRK_PWM_N_REGS_LEN; + } + + MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, ((channel * regs_len) + + offset)) = val; +} + +static DRIVER_API_RC soc_pwm_check_config(struct soc_pwm_channel_config *config) +{ + DRIVER_API_RC ret = DRV_RC_OK; + + if (config->channel_num > QRK_PWM_NPWM) + { + ret = DRV_RC_INVALID_CONFIG; + } + + if (PWM_MODE == config->mode) + { + if (0 == config->pwm_period_ns || 0 == config->pwm_duty_cycle_ns || + config->pwm_duty_cycle_ns > config->pwm_period_ns || + config->pwm_duty_cycle_ns > DUTY_CYCLE_MAX_NS || + config->pwm_period_ns > PERIOD_MAX_NS) + { + ret = DRV_RC_INVALID_CONFIG; + } + } + + else + { + if (0 == config->timer_timeout_ns || config->timer_timeout_ns > TIMER_TIMEOUT_MAX_NS) + { + ret = DRV_RC_INVALID_CONFIG; + } + } + + if (config->mode != PWM_MODE && config->mode != TIMER_MODE) + { + ret = DRV_RC_INVALID_CONFIG; + } + + return ret; +} + +/*! \fn DRIVER_API_RC soc_pwm_set_config(struct soc_pwm_channel_config *config) +* +* \brief Function to configure a specified PWM channel +* +* \param config : pointer to a channel configuration structure +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_pwm_set_config(struct soc_pwm_channel_config *config) +{ + uint64_t duty_cycle = 0, period = 0; + uint32_t hcnt = 0, lcnt = 0, val = 0; + + /* Dont go any further if config is bad */ + if(soc_pwm_check_config(config) != DRV_RC_OK) + { + return DRV_RC_INVALID_CONFIG; + } + + /* Manage differences between PWM and timer mode */ + val = soc_pwm_ioread(config->channel_num, QRK_PWM_N_CONTROL); + + if(PWM_MODE == config->mode) + { + duty_cycle = config->pwm_duty_cycle_ns; + period = config->pwm_period_ns; + + /* if PWM_MODE enable output */ + val |= QRK_PWM_CONTROL_PWM_OUT; + } + + + if(TIMER_MODE == config->mode) + { + duty_cycle = config->timer_timeout_ns; + period = (config->timer_timeout_ns * 2); + + one_shot[config->channel_num] = config->timer_enable_oneshot; + + /* if TIMER_MODE disable output */ + val &= ~QRK_PWM_CONTROL_PWM_OUT; + } + + soc_pwm_iowrite(config->channel_num, QRK_PWM_N_CONTROL, val); + + + /* Calculate value for count for LoadCount1 and LoadCount2 register */ + /* Values are multiplied by 100 to increase accuracy + * without the use of floats */ + hcnt = (uint32_t) ((duty_cycle * 100)/GRANULARITY_X_100); + lcnt = (uint32_t) (((period * 100) - (duty_cycle * 100))/GRANULARITY_X_100); + + + /* A count of 0, equates to (1 * granularity), so adjust by -1 */ + if (hcnt > 0) + { + hcnt--; + } + + if (lcnt > 0) + { + lcnt--; + } + + /* Load counter value */ + soc_pwm_iowrite(config->channel_num, QRK_PWM_N_LOAD_COUNT2, hcnt); + soc_pwm_iowrite(config->channel_num, QRK_PWM_N_LOAD_COUNT1, lcnt); + + /* Interrupt masking/unmasking and channel specific interrupt functions */ + if (TRUE == config->pwm_enable_interrupts || TIMER_MODE == config->mode) + { + soc_pwm_unmask_interrupt(config->channel_num); + callback_fn[config->channel_num] = config->interrupt_fn; + } + + else + { + soc_pwm_mask_interrupt(config->channel_num); + } + + return DRV_RC_OK; +} + +/*! \fn void soc_pwm_start(int channel) +* +* \brief Function to start a pwm/timer channel +* +* \param channel : Channel number +*/ + +void soc_pwm_start(uint8_t channel) +{ + uint32_t val = 0; + + /* Read/Write protection */ + /* Protect QRK_PWM_N_CONTROL using lock and unlock of interruptions */ + uint32_t saved = interrupt_lock(); + + val = soc_pwm_ioread(channel, QRK_PWM_N_CONTROL); + val |= QRK_PWM_CONTROL_ENABLE; + soc_pwm_iowrite(channel, QRK_PWM_N_CONTROL, val); + interrupt_unlock(saved); +} + +/*! \fn void soc_pwm_stop(int channel) +* +* \brief Function to stop a pwm/timer channel +* +* \param channel : Channel number +*/ +void soc_pwm_stop(uint8_t channel) +{ + uint32_t val = 0; + + /* Read/Write protection */ + /* Protect QRK_PWM_N_CONTROL using lock and unlock of interruptions */ + uint32_t saved = interrupt_lock(); + + val = soc_pwm_ioread(channel, QRK_PWM_N_CONTROL); + val &= ~QRK_PWM_CONTROL_ENABLE; + soc_pwm_iowrite(channel, QRK_PWM_N_CONTROL, val); + interrupt_unlock(saved); +} + +static void soc_pwm_mask_interrupt(uint8_t channel) +{ + uint32_t val = 0; + + /* Read/Write protection */ + /* Protect QRK_PWM_N_CONTROL using lock and unlock of interruptions */ + uint32_t saved = interrupt_lock(); + + val = soc_pwm_ioread(channel, QRK_PWM_N_CONTROL); + val |= QRK_PWM_CONTROL_INT_MASK; + soc_pwm_iowrite(channel, QRK_PWM_N_CONTROL, val); + interrupt_unlock(saved); +} + +static void soc_pwm_unmask_interrupt(uint8_t channel) +{ + uint32_t val = 0; + + /* Read/Write protection */ + /* Protect QRK_PWM_N_CONTROL using lock and unlock of interruptions */ + uint32_t saved = interrupt_lock(); + + val = soc_pwm_ioread(channel, QRK_PWM_N_CONTROL); + val &= ~QRK_PWM_CONTROL_INT_MASK; + soc_pwm_iowrite(channel, QRK_PWM_N_CONTROL, val); + interrupt_unlock(saved); +} + +/* ! \fn void pwm_isr(void) + * + * \brief PWM ISR, if specified calls a user defined callback + */ +DECLARE_INTERRUPT_HANDLER void pwm_isr(void *arg) +{ + uint32_t pending = 0, pwm = 0; + + /* Which pin (if any) triggered the interrupt */ + while ((pending = MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, QRK_PWMS_INT_STATUS))) + { + + do { + if (pending & 0x01) + { + pwm = 0; + pending &= ~0x01; + } + + else if (pending & 0x02) + { + pwm = 1; + pending &= ~0x02; + } + + else if (pending & 0x04) + { + pwm = 2; + pending &= ~0x04; + } + + else if (pending & 0x08) + { + pwm = 3; + pending &= ~0x08; + } + + if (callback_fn[pwm]) + { + (*callback_fn[pwm])(); + } + + if (TRUE == one_shot[pwm]) + { + soc_pwm_stop(pwm); + } + + } while (pending); + + /* Clear the interrupt */ + MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, QRK_PWMS_EOI); + } +} + +/*! \fn DRIVER_API_RC soc_pwm_block_init(void) +* +* \brief Function to initialise PWM controller. WARNING: This must be run before configuring a PWM channel. +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_pwm_block_init(void) +{ + int i = 0; + uint32_t val = 0; + /* Read/Write protection */ + /* Protect QRK_PWM_N_CONTROL using lock and unlock of interruptions */ + uint32_t saved = interrupt_lock(); + + for (i = 0; i < QRK_PWM_NPWM; i++) + { + val = soc_pwm_ioread(i, QRK_PWM_N_CONTROL); + + /* Mask interrupts */ + val |= QRK_PWM_CONTROL_INT_MASK; + + /* Set timer mode periodic- + * EAS "Free-running timer mode is not supported + * (i.e. TimerXControlReg.”Timer Mode” must be set to b1)*/ + val |= QRK_PWM_CONTROL_MODE_PERIODIC; + soc_pwm_iowrite(i, QRK_PWM_N_CONTROL, val); + } + interrupt_unlock(saved); + + SET_INTERRUPT_HANDLER(SOC_PWM_INTERRUPT, pwm_isr); + + /* unmask pwm ints to arc core */ + SOC_UNMASK_INTERRUPTS(SCSS_INT_PWM_TIMER_MASK_OFFSET); + + return DRV_RC_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/system/libarc32_edu/drivers/intel_qrk_pwm.h b/system/libarc32_edu/drivers/intel_qrk_pwm.h new file mode 100644 index 00000000..75ac002b --- /dev/null +++ b/system/libarc32_edu/drivers/intel_qrk_pwm.h @@ -0,0 +1,138 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef INTEL_QRK_PWM_H_ +#define INTEL_QRK_PWM_H_ + +/** + * \addtogroup common_drivers + * @{ + * \defgroup pwm PWM: Pulse Width Modulation API + * @{ + * \brief Definition of the structure and functions used by PWM Driver implementation. + */ + +#include "data_type.h" + +/* Number of available PWM channels available on the + FST Quark platform */ +#define QRK_PWM_NPWM 4 + +/* Max duty cycle at slowest PWM pulse frequency 100% at 1/60th of a hertz */ +#define DUTY_CYCLE_MAX_NS 60000000000 +/* Slowest supported PWM pulse freqency - 1/60th of a hertz */ +#define PERIOD_MAX_NS 60000000000 +/* Max timer timeout - 60 seconds */ +#define TIMER_TIMEOUT_MAX_NS 60000000000 + +/* + * Mode of operation + */ +typedef enum{ + PWM_MODE = 0, + TIMER_MODE +}soc_pwm_mode_t; + +/*! + * \brief PWM channel configuration + * The user instantiates one of these with given parameters for each PWM + * channel, configured using the "soc_pwm_set_config" function + */ +struct soc_pwm_channel_config{ + uint8_t channel_num; /*!< Channel number 1-4 */ + soc_pwm_mode_t mode; /*!< Operation Mode- PWM or timer mode */ + uint64_t pwm_period_ns; /*!< PWM period in nanoseconds - PWM mode only */ + uint64_t pwm_duty_cycle_ns; /*!< PWM duty cycle in nanoseconds (time high) - PWM mode only */ + boolean_t pwm_enable_interrupts;/*!< Enable all edge interrupts - PWM mode only */ + uint64_t timer_timeout_ns; /*!< Timer timeout in nanoseconds - timer mode only*/ + boolean_t timer_enable_oneshot; /*!< Enable one shot timer mode - timer mode only */ + void (*interrupt_fn) (void); /*!< Pointer to function to call when a channel specific PWM interrupt fires or a timer expires */ +}; + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn void soc_pwm_enable(void) +* +* \brief Function disable clock gating for the PWM device +*/ +void soc_pwm_enable(void); + +/*! \fn void soc_pwm_disable(void) +* +* \brief Function to enable clock gating for the PWM device +*/ +void soc_pwm_disable(void); + +/*! \fn DRIVER_API_RC soc_pwm_set_config(struct soc_pwm_channel_config *config) +* +* \brief Function to configure a specified PWM channel +* +* \param config : pointer to a channel configuration structure +* +* \return RC_OK on success\n +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_pwm_set_config(struct soc_pwm_channel_config *config); + +/*! \fn void soc_pwm_start(int channel) +* +* \brief Function to start a pwm/timer channel +* +* \param channel : Channel number +*/ +void soc_pwm_start(uint8_t channel); + +/*! \fn void soc_pwm_stop(int channel) +* +* \brief Function to stop a pwm/timer channel +* +* \param channel : Channel number +*/ +void soc_pwm_stop(uint8_t channel); + +/*! \fn DRIVER_API_RC soc_pwm_block_init(void) +* +* \brief Function to initialise PWM controller. WARNING: This must be run before configuring a PWM channel. +* +* \return RC_OK on success\n +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_pwm_block_init(void); + + +/*! \fn void pwm_isr(void*) + * + * \brief PWM ISR, if specified calls a user defined callback + */ +void pwm_isr(void*); + +#ifdef __cplusplus +} +#endif + +#endif /* INTEL_QRK_PWM_H_ */ + +/**@} @}*/ diff --git a/system/libarc32_edu/drivers/intel_qrk_spi.c b/system/libarc32_edu/drivers/intel_qrk_spi.c new file mode 100644 index 00000000..993bf899 --- /dev/null +++ b/system/libarc32_edu/drivers/intel_qrk_spi.c @@ -0,0 +1,549 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ +/* + * Intel SOC SPI driver + * + */ + +#include "soc_register.h" +#include "soc_spi_priv.h" +#include "intel_qrk_spi.h" +#include "portable.h" +#include "string.h" + +/* Software workaround: + * -------------------- + * We are currently encountering problems with the SPI0_Master chip select. + * Although it should be drived automatically by the spi module itself during a transaction, + * it is not the case. + * This software workaround allows driving directly the cs pin using gpios. + * */ +#define ATP_HW_V1 + +#if 0 +#define DEBUG_SPI_DRIVER +extern int printk(const char *, ...); +#define DBG(args...) printk(args); +#else +#define DBG(args...) +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +static DRIVER_API_RC is_valid_controller(SOC_SPI_CONTROLLER id); +static void copy_config_data(spi_cfg_data_t *cfg, SOC_SPI_CONTROLLER controller_id); +/* IT subrountines */ + +static void spi_fill_fifo(soc_spi_info_pt dev); + +struct soc_spi_cfg_driver_data +{ + spi_cfg_data_t cfg; + uint16_t tx_threshold; + uint16_t rx_threshold; + SHIFT_REG_LOOP srl; +}; + +#define SPI_MAX_CNT (3) + +static struct soc_spi_cfg_driver_data drv_config[SPI_MAX_CNT]; + +/* SPI master devices private data structures */ +static soc_spi_info_pt spi_handles[SPI_MAX_CNT] = { 0 }; + +/* Interrupt Service Routines */ +void soc_spi_mst0_ISR() +{ + soc_spi_ISR_proc(spi_handles[SOC_SPI_MASTER_0]); +} +void soc_spi_mst1_ISR() +{ + soc_spi_ISR_proc(spi_handles[SOC_SPI_MASTER_1]); +} +void soc_spi_slv_ISR() +{ + soc_spi_ISR_proc(spi_handles[SOC_SPI_SLAVE_0]); +} + +static soc_spi_info_t soc_spi_devs[] = { + { .instID = SOC_SPI_MASTER_0, + .reg_base = SOC_MST_SPI0_REGISTER_BASE, + .isr_vector = SOC_SPIM0_INTERRUPT, + .isr = soc_spi_mst0_ISR, + .fifo_depth = IO_SPI_MST0_FS, + .spi_int_mask = INT_SPI_MST_0_MASK + }, + { .instID = SOC_SPI_MASTER_1, + .reg_base = SOC_MST_SPI1_REGISTER_BASE, + .isr_vector = SOC_SPIM1_INTERRUPT, + .isr = soc_spi_mst1_ISR, + .fifo_depth = IO_SPI_MST1_FS, + .spi_int_mask = INT_SPI_MST_1_MASK + }, + { .instID = SOC_SPI_SLAVE_0, + .reg_base = SOC_SLV_SPI_REGISTER_BASE, + .isr_vector = SOC_SPIS0_INTERRUPT, + .isr = soc_spi_slv_ISR, + .fifo_depth = IO_SPI_SLV_FS, + .spi_int_mask = INT_SPI_SLV_MASK + }, + { .instID = SPI_MAX_CNT + } + }; + +#ifdef ATP_HW_V1 +static void cs_config(uint8_t gpio) +{ + MMIO_REG_VAL_FROM_BASE(SOC_GPIO_BASE_ADDR, SOC_GPIO_SWPORTA_DDR) |= (1<reg_base, SPIEN) &= SPI_DISABLE; + + /* Set frame size, bus mode and transfer mode */ + reg = (drv_cfg->cfg.data_frame_size << 16) | (drv_cfg->cfg.loopback_enable << 11) | + (drv_cfg->cfg.bus_mode << 6) | (drv_cfg->cfg.txfr_mode << 8 ); + + MMIO_REG_VAL_FROM_BASE(dev->reg_base, CTRL0) = reg; + // TODO data_frame_size is not written to CTRL0 - default is 8 bit + + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFTL) = drv_cfg->tx_threshold; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFTL) = drv_cfg->rx_threshold; + + /* If the device is configured as a slave, an external master will set the baud rate */ + if(SOC_SPI_SLAVE_0 != controller_id) + { + /* Set SPI Clock Divider */ + reg = (FREQ_SPI_CLOCK_IN / (drv_cfg->cfg.speed*BAUD_DIVISOR)); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, BAUDR) = reg; + } + else + { + /* Full duplex setup order for slave is initially unassigned */ + dev->fd_order = UNASSIGNED; + } + + dev->dfs = drv_cfg->cfg.data_frame_size; + dev->rx_len = 0; + dev->tx_len = 0; + dev->mode = drv_cfg->cfg.txfr_mode; + dev->state = SPI_STATE_IDLE; + + /* User callbacks */ + dev->err_cb = drv_cfg->cfg.cb_err; + dev->xfer_cb = drv_cfg->cfg.cb_xfer; + dev->slave_rx_cb = drv_cfg->cfg.cb_slave_rx; + dev->cb_xfer_data = drv_cfg->cfg.cb_xfer_data; + dev->cb_err_data = drv_cfg->cfg.cb_err_data; + + /* Register ISR */ + SET_INTERRUPT_HANDLER( dev->isr_vector, dev->isr); + + /* Setup SPI Interrupt Routing Mask Registers to allow interrupts through */ + SOC_UNMASK_INTERRUPTS(dev->spi_int_mask); + + /* Disable interrupts */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = SPI_DISABLE_INT; + /* Enable device */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SPIEN) |= SPI_ENABLE; + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_spi_get_config(SOC_SPI_CONTROLLER controller_id, spi_cfg_data_t *config) +{ + // TODO - Check for no config structure + config = &drv_config[controller_id].cfg; + return DRV_RC_OK; +} + +DRIVER_API_RC soc_spi_deconfig(SOC_SPI_CONTROLLER controller_id) +{ + soc_spi_info_pt dev = 0; + + dev = &soc_spi_devs[controller_id]; + + /* disable controller */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SPIEN) &= SPI_DISABLE; + + /* Set SPI registers to hardware reset state */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, BAUDR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFTL) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFTL) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFL) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFL) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, ISR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RISR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFOIC) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFOIC) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFUIC) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, MMIC) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, ICR) = 0x0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IDR) = 0x0; + + /* Disable clock to peripheral */ + soc_spi_clock_disable(controller_id); + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_spi_clock_enable(SOC_SPI_CONTROLLER controller_id) +{ + /* Enable clock to peripheral */ + if(SOC_SPI_MASTER_0 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= ENABLE_SPI_MASTER_0; + } + else if (SOC_SPI_MASTER_1 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= ENABLE_SPI_MASTER_1; + } + else if (SOC_SPI_SLAVE_0 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= ENABLE_SPI_SLAVE; + } + else + { + return DRV_RC_INVALID_OPERATION; + } + return DRV_RC_OK; +} + +DRIVER_API_RC soc_spi_clock_disable(SOC_SPI_CONTROLLER controller_id) +{ + /* Disable clock to peripheral */ + if(SOC_SPI_MASTER_0 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= DISABLE_SPI_MASTER_0; + } + else if (SOC_SPI_MASTER_1 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= DISABLE_SPI_MASTER_1; + } + else if (SOC_SPI_SLAVE_0 == controller_id) + { + MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= DISABLE_SPI_SLAVE; + } + else + { + return DRV_RC_INVALID_OPERATION; + } + + return DRV_RC_OK; +} + +#ifdef ATP_HW_V1 +DRIVER_API_RC soc_spi_cs_hook(soc_spi_info_pt dev, int slave) +{ + /* If SPI_M0, use GPIO mode */ + if(dev->instID == SOC_SPI_MASTER_0) + { + switch(slave) + { + case SPI_SE_1: + { + dev->cs_gpio = SPIM0_CS_1_GPIO24; + break; + } + case SPI_SE_2: + { + dev->cs_gpio = SPIM0_CS_2_GPIO25; + break; + } + case SPI_SE_3: + { + dev->cs_gpio = SPIM0_CS_3_GPIO26; + break; + } + case SPI_SE_4: + { + dev->cs_gpio = SPIM0_CS_4_GPIO27; + break; + } + default: + { + return DRV_RC_INVALID_OPERATION; + } + } + cs_config(dev->cs_gpio); + cs_low(dev->cs_gpio); + } + return DRV_RC_OK; +} +#endif + +DRIVER_API_RC soc_spi_transfer(SOC_SPI_CONTROLLER controller_id, uint8_t *tx_data, uint32_t tx_data_len, uint8_t *rx_data, uint32_t rx_data_len, int full_duplex, SPI_SLAVE_ENABLE slave) +{ + DRIVER_API_RC ret; + soc_spi_info_pt dev = &soc_spi_devs[controller_id]; + + /* Check if device is in use */ + if (soc_spi_status(controller_id) == SPI_BUSY) + { + return DRV_RC_CONTROLLER_IN_USE; + } + + if (full_duplex && (rx_data_len < tx_data_len)) { + return DRV_RC_INVALID_OPERATION; + } + + /* Setup communication parameters */ + dev->tx_len = tx_data_len; + dev->tx_buf = tx_data; + dev->rx_count = dev->tx_count = 0; + dev->rx_len = rx_data_len; + dev->rx_buf = rx_data; + dev->discarded = 0; + dev->dummy_tx = 0; + + dev->full_duplex = full_duplex; + + /* Disable device */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SPIEN) &= SPI_DISABLE; + + //TODO: This might be used when we use the hw driven CS / not GPIO. + //MMIO_REG_VAL_FROM_BASE(dev->reg_base, CTRL1) = dev->tx_len + dev->rx_len - 1; + + /* Enable slave device */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SER) = slave; + + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = SPI_DISABLE_INT; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, ICR); + + /* Enable device */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SPIEN) |= SPI_ENABLE; + +#ifdef ATP_HW_V1 + ret = soc_spi_cs_hook(dev, slave); + if (ret != DRV_RC_OK) + { + return ret; + } +#endif + + spi_fill_fifo(dev); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = SPI_ENABLE_INT; + return DRV_RC_OK; +} + +DRIVER_SPI_STATUS_CODE soc_spi_status(SOC_SPI_CONTROLLER controller_id) +{ + DRIVER_SPI_STATUS_CODE rc = SPI_OK; + soc_spi_info_pt dev = &soc_spi_devs[controller_id]; + uint32_t status = 0; + + status = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR); + if ((status & SPI_STATUS_BUSY)){ + rc = SPI_BUSY; + } + else if ((status & SPI_STATUS_TFE)){ + rc = SPI_TFE; + } + else if ((status & SPI_STATUS_RFNE)){ + rc = SPI_RFNE; + } + return rc; +} + +/* + * Check to see if this controller is part of the design ( determined at build time ) + */ +static DRIVER_API_RC is_valid_controller(SOC_SPI_CONTROLLER id) +{ + // TODO + // do checks here + return DRV_RC_OK; +} + +static void copy_config_data(spi_cfg_data_t *cfg, SOC_SPI_CONTROLLER controller_id) +{ + /* copy passed in config data locally */ + memcpy(&drv_config[controller_id].cfg, cfg, sizeof(drv_config[controller_id].cfg)); + + drv_config[controller_id].tx_threshold = SPI_TX_FIFO_THRESHOLD; + drv_config[controller_id].rx_threshold = SPI_RX_FIFO_THRESHOLD; + drv_config[controller_id].srl = NORMAL_MODE; + +} + +void transfer_complete(soc_spi_info_pt dev) +{ + uint32_t tmp; + + do + { + tmp = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR); + } while((tmp&SPI_STATUS_BUSY)); + + dev->state = SPI_STATE_IDLE; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = SPI_DISABLE_INT; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, ICR); + +#ifdef ATP_HW_V1 + if(dev->instID == SOC_SPI_MASTER_0) + { + cs_high(dev->cs_gpio); + } +#endif + if (dev->xfer_cb != NULL) + { + dev->xfer_cb(dev->cb_xfer_data); + } +} + +void spi_fill_fifo(soc_spi_info_pt dev) +{ + uint32_t status = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR); + DBG("%s: status: %x tc: %d rc: %d tlen: %d rlen: %d\n", __func__, status, + dev->tx_count, dev->rx_count, dev->tx_len, dev->rx_len); + while( (status & SPI_STATUS_TFNF) && + ((MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFL) + + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFL)) < dev->fifo_depth )) { + if (dev->tx_count < dev->tx_len) + { + DBG("push data\n"); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, DR) = dev->tx_buf[dev->tx_count++]; + if (dev->full_duplex) + { + dev->dummy_tx++; + } + } + else if (dev->dummy_tx < dev->rx_len) + { + DBG("push dummy\n"); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, DR) = 0; + dev->dummy_tx ++; + } + else + { + /* xfer complete, wait for last tx_empty and wait for end of reception. */ + break; + } + status = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR); + } +} + + +void soc_spi_ISR_proc(soc_spi_info_pt dev) +{ + uint32_t status = MMIO_REG_VAL_FROM_BASE(dev->reg_base, ISR); + uint32_t clear = MMIO_REG_VAL_FROM_BASE(dev->reg_base, ICR); +#ifndef DEBUG_SPI_DRIVER + (void)clear; /* Unused variable */ +#endif + DBG("I %x M:%x", status, MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR)); + if (status == 0) { + return; + } + DBG("Interrupt : cl %x rxl: %d txl: %d\n", clear, + MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFL), + MMIO_REG_VAL_FROM_BASE(dev->reg_base, TXFL)); + DBG("%s: status: %x tc: %d rc: %d tlen: %d rlen: %d\n", __func__, status, + dev->tx_count, dev->rx_count, dev->tx_len, dev->rx_len); + + /* Receive data */ + while(MMIO_REG_VAL_FROM_BASE(dev->reg_base, RXFL) > 0) + { + if (!dev->full_duplex && (dev->discarded < dev->tx_len)) + { + uint32_t tmp; + tmp = MMIO_REG_VAL_FROM_BASE(dev->reg_base, DR); + DBG("discard %x\n", tmp); + dev->discarded++; + } else { + if( dev->rx_count < dev->rx_len) + { + dev->rx_buf[dev->rx_count++] = MMIO_REG_VAL_FROM_BASE(dev->reg_base, DR); + DBG("pop %x\n", dev->rx_buf[dev->rx_count -1 ]); + } + } + if ((dev->rx_len > 0) && (dev->rx_count == dev->rx_len)) + { + transfer_complete(dev); + return; + } + } + + if (MMIO_REG_VAL_FROM_BASE(dev->reg_base, SR) & SPI_STATUS_TFE) + { + if (dev->tx_len > 0 && (dev->tx_count == dev->tx_len) && dev->rx_len == 0) + { + transfer_complete(dev); + return; + } + } + + if ((dev->rx_count < dev->rx_len) || (dev->tx_count < dev->tx_len)) + { + spi_fill_fifo(dev); + } + + DBG("%s: status: %x tc: %d rc: %d tl: %d rl: %d\n", __func__, status, + dev->tx_count, dev->rx_count, dev->tx_len, dev->rx_len); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = 0; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, IMR) = SPI_ENABLE_INT; +} + +#ifdef __cplusplus +} +#endif diff --git a/system/libarc32_edu/drivers/intel_qrk_spi.h b/system/libarc32_edu/drivers/intel_qrk_spi.h new file mode 100644 index 00000000..5550558c --- /dev/null +++ b/system/libarc32_edu/drivers/intel_qrk_spi.h @@ -0,0 +1,171 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ +/* + * Intel SOC SPI driver + * + */ + +#ifndef INTEL_QRK_SPI_H_ +#define INTEL_QRK_SPI_H_ + +/** + * \addtogroup common_drivers + * @{ + * \defgroup spi SPI: Serial Peripheral Interface API + * @{ + * \brief Definition of the structure and functions used by SPI Driver implementation. + */ + +#include "data_type.h" +#include "common_spi.h" + +/*! + * Clock speed into SPI peripheral - set at compile time + */ +#define FREQ_SPI_CLOCK_IN (CLOCK_SPEED*1000*1000) /* CLOCK_SPEED in MHz */ + +/*! + * List of all controllers in host processor + */ +typedef enum { + SOC_SPI_MASTER_0 = 0, /* SPI master controller 0, accessible by both processing entities */ + SOC_SPI_MASTER_1, /* SPI master controller 1, accessible by both processing entities */ + SOC_SPI_SLAVE_0 /* SPI slave controller */ +}SOC_SPI_CONTROLLER; + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn DRIVER_API_RC soc_spi_set_config(SOC_SPI_CONTROLLER controller_id, spi_cfg_data_t *config) +* +* \brief Function to configure specified SPI controller +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param controller_id : SPI controller identifier +* \param config : pointer to configuration structure +* +* \return RC_OK - on success, +* RC_DEVICE_TYPE_NOT_SUPPORTED - if device type is not supported by this controller +* RC_INVALID_CONFIG - if any configuration parameters are not valid +* RC_CONTROLLER_IN_USE, - if controller is in use +* RC_CONTROLLER_NOT_ACCESSIBLE - if controller is not accessible from this core +* RC_FAIL - otherwise +*/ +DRIVER_API_RC soc_spi_set_config(SOC_SPI_CONTROLLER controller_id, spi_cfg_data_t *config); + +/*! \fn DRIVER_API_RC soc_spi_get_config(SOC_SPI_CONTROLLER controller_id, spi_cfg_data_t *config) +* +* \brief Function to retrieve configuration of specified SPI controller +* +* \param controller_id : SPI controller identifier +* \param config : pointer to configuration structure to store current setup +* +* \return RC_OK - on success +* RC_FAIL - otherwise +*/ +DRIVER_API_RC soc_spi_get_config(SOC_SPI_CONTROLLER controller_id, spi_cfg_data_t *config); + +/*! \fn DRIVER_API_RC soc_spi_deconfig(SOC_SPI_CONTROLLER controller_id) +* +* \brief Function to place SPI controller into a disabled and default state (as if hardware reset occurred) +* This function assumes that there is no pending transaction on the SPI interface in question. +* It is the responsibility of the calling application to do so. +* Upon success, the specified SPI interface is clock gated in hardware, +* it is no longer capable to generating interrupts, it is also configured into a default state +* +* \param controller_id : SPI controller identifier +* +* \return RC_OK on success +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_spi_deconfig(SOC_SPI_CONTROLLER controller_id); + +/*! \fn DRIVER_API_RC soc_spi_clock_enable(SOC_SPI_CONTROLLER controller_id) +* +* \brief Function to enable the specified SPI controller +* Upon success, the specified SPI interface is no longer clock gated in hardware, it is now +* capable of transmitting and receiving on the SPI bus and of generating interrupts. +* +* \param controller_id : SPI controller identifier +* +* \return RC_OK on success +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_spi_clock_enable(SOC_SPI_CONTROLLER controller_id); + +/*! \fn DRIVER_API_RC soc_spi_clock_disable(SOC_SPI_CONTROLLER controller_id) +* +* \brief Function to disable the specified SPI controller. +* This function assumes that there is no pending transaction on the SPI interface in question. +* It is the responsibility of the calling application to do so. +* Upon success, the specified SPI interface is clock gated in hardware, +* it is no longer capable of generating interrupts. +* +* \param controller_id : SPI controller identifier +* +* \return RC_OK on success +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_spi_clock_disable(SOC_SPI_CONTROLLER controller_id); + +/*! \fn DRIVER_API_RC soc_spi_transfer(SOC_SPI_CONTROLLER controller_id, uint8_t *tx_data, uint32_t tx_data_len, uint8_t *rx_data, uint32_t rx_data_len, SOC_SPI_SLAVE_ENABLE slave) +* +* \brief Function to send a command and receive a result from the specified SPI slave +* +* \param controller_id : SPI controller identifier +* \param tx_data : pointer to cmd to transmit +* \param tx_data_len : length of cmd to transmit +* \param rx_data : pointer to data to receive +* \param rx_data_len : length of data to receive +* \param full_duplex : set to 1 if data received between tx_phase should be put in rx_data buffer +* rx_data_len should be >= tx_data_len ! +* \param slave : slave device to TX to and receive from +* +* \return RC_OK - on success +* RC_CONTROLLER_IN_USE - when device is busy +* RC_FAIL - otherwise +*/ +DRIVER_API_RC soc_spi_transfer(SOC_SPI_CONTROLLER controller_id, uint8_t *tx_data, uint32_t tx_data_len, uint8_t *rx_data, uint32_t rx_data_len, int full_duplex, SPI_SLAVE_ENABLE slave); + +/*! \fn DRIVER_SPI_STATUS_CODE soc_spi_status(SOC_SPI_CONTROLLER controller_id) +* +* \brief Function to determine controllers current state +* +* \param controller_id : SPI controller identifier +* +* \return SOC_SPI_OK - controller ready +* SOC_SPI_BUSY - controller busy +* SOC_SPI_TFE - TX FIFO Empty +* SOC_SPI_RFNE - RX FIFO Not Empty +*/ +DRIVER_SPI_STATUS_CODE soc_spi_status(SOC_SPI_CONTROLLER controller_id); + +#ifdef __cplusplus +} +#endif + +/**@} @}*/ + +#endif /* INTEL_QRK_SPI_H_ */ diff --git a/system/libarc32_edu/drivers/io_config.h b/system/libarc32_edu/drivers/io_config.h new file mode 100644 index 00000000..eb134ce9 --- /dev/null +++ b/system/libarc32_edu/drivers/io_config.h @@ -0,0 +1,94 @@ + +/* **** DO NOT EDIT - this file is generated by ARChitect2 **** + * + * Description: Header file declaring the compiler extensions for eia components + */ + +#ifndef _io_config_H_ +#define _io_config_H_ + +/* Original version from Synopsys toolchain ....*/ +#define IO_ADC0_PRESENT +#define IO_ADC0_FS (32) +#define IO_ADC0_SE (32) +#define IO_ADC0_INT_ERR (18) +#define IO_ADC0_INT_IRQ (19) +#define IO_CREG_MST0_PRESENT +#define IO_CREG_SLV0_PRESENT +#define IO_CREG_SLV1_PRESENT +#define IO_GPIO_8B0_PRESENT +#define IO_GPIO_8B0_INT_INTR_FLAG (20) +#define IO_GPIO_8B1_PRESENT +#define IO_GPIO_8B1_INT_INTR_FLAG (21) +#define IO_I2C_MST0_PRESENT +#define IO_I2C_MST0_FS (8) +#define IO_I2C_MST0_INT_ERR (22) +#define IO_I2C_MST0_INT_RX_AVAIL (23) +#define IO_I2C_MST0_INT_TX_REQ (24) +#define IO_I2C_MST0_INT_STOP_DETECTED (25) +#define IO_I2C_MST1_PRESENT +#define IO_I2C_MST1_FS (8) +#define IO_I2C_MST1_INT_ERR (26) +#define IO_I2C_MST1_INT_RX_AVAIL (27) +#define IO_I2C_MST1_INT_TX_REQ (28) +#define IO_I2C_MST1_INT_STOP_DETECTED (29) +#define IO_SPI_MST0_PRESENT +#define IO_SPI_MST0_FS (8) +#define IO_SPI_MST0_INT_ERR (30) +#define IO_SPI_MST0_INT_RX_AVAIL (31) +#define IO_SPI_MST0_INT_TX_REQ (32) +#define IO_SPI_MST1_PRESENT +#define IO_SPI_MST1_FS (8) +#define IO_SPI_MST1_INT_ERR (33) +#define IO_SPI_MST1_INT_RX_AVAIL (34) +#define IO_SPI_MST1_INT_TX_REQ (35) + + + +// Need to decide where these should reside - probably some common header file +//@@@ +// TODO Add description for these macros +#define NUM_INTERRUPTS 256 + +#define AUX_IRQ_CTRL_SAVE_ALL (0x1F | (1 << 9) | (1 << 10)) +#define AUX_IRQ_CTRL 0x0E + +#define AUX_IRQ_SELECT 0x40B +#define AUX_IRQ_PRIO 0x206 + +#define AUX_REG_IVT_BASE 0x25 + +#define CLR_INT asm("CLRI;") +#define SET_INT asm("SETI;") + +#define I2C_PRIORITY 1 +#define SPI_PRIORITY 1 +#define MAILBOX_INTERRUPT_PRIORITY 1 +#define UART_PRIORITY 1 +#define GPIO_PRIORITY 1 +#define DMAC_PRIORITY 1 + +#define MAILBOX_SS_INT_VECTOR (57) + +// UART0 +#define IO_UART0_INT (41) +#define IO_UART1_INT (42) + +// I2C +#define SOC_I2C_0_INT (36) +#define SOC_I2C_1_INT (37) + +// DMAC +#define DMA_CHANNEL_0_INT (49) +#define DMA_CHANNEL_1_INT (50) +#define DMA_CHANNEL_2_INT (51) +#define DMA_CHANNEL_3_INT (52) +#define DMA_CHANNEL_4_INT (53) +#define DMA_CHANNEL_5_INT (54) +#define DMA_CHANNEL_6_INT (55) +#define DMA_CHANNEL_7_INT (56) +#define DMA_ERROR_INT (60) + +#endif + + diff --git a/system/libarc32_edu/drivers/soc_gpio.c b/system/libarc32_edu/drivers/soc_gpio.c new file mode 100644 index 00000000..2294c146 --- /dev/null +++ b/system/libarc32_edu/drivers/soc_gpio.c @@ -0,0 +1,438 @@ +/** INTEL CONFIDENTIAL Copyright 2014-2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#include "soc_gpio.h" + +#if defined(CONFIG_SOC_GPIO_32) || defined(CONFIG_SOC_GPIO_AON) + +#include "soc_register.h" +#include "portable.h" + +#define GPIO_CLKENA_POS (31) +#define GPIO_LS_SYNC_POS (0) + +#ifdef __cplusplus + extern "C" { +#endif + +static void soc_gpio_ISR_proc( uint32_t dev_id ); + +#if defined(CONFIG_SOC_GPIO_32) +/*! \brief Interrupt handler for GPIO port 0 (32 bits) + */ +DECLARE_INTERRUPT_HANDLER void gpio_isr() +{ + soc_gpio_ISR_proc(SOC_GPIO_32); +} +static gpio_callback_fn soc_gpio_32_cb[SOC_GPIO_32_BITS] = {NULL}; +static void* soc_gpio_32_arg[SOC_GPIO_32_BITS] = {NULL}; +#endif + +#if defined(CONFIG_SOC_GPIO_AON) +/*! \brief Interrupt handler for GPIO port 1 (aon, 6 bits) + */ +DECLARE_INTERRUPT_HANDLER void gpio_aon_isr() +{ + soc_gpio_ISR_proc(SOC_GPIO_AON); +} +static gpio_callback_fn soc_gpio_aon_cb[SOC_GPIO_AON_BITS] = {NULL}; +static void* soc_gpio_aon_arg[SOC_GPIO_AON_BITS] = {NULL}; +#endif + +typedef void (*ISR) (); + +/*! GPIO management structure */ +typedef struct gpio_info_struct +{ + /* static settings */ + uint32_t reg_base; /*!< base address of device register set */ + uint8_t no_bits; /*!< no of gpio bits in this entity */ + uint8_t vector; /*!< GPIO ISR vector */ + ISR gpio_isr; /*!< GPIO ISR */ + uint32_t gpio_int_mask; /*!< SSS Interrupt Routing Mask Registers */ + gpio_callback_fn *gpio_cb; /*!< Array of user callback functions for user */ + void **gpio_cb_arg; /*!< Array of user priv data for callbacks */ + uint8_t is_init; /*!< Init state of GPIO port */ +} gpio_info_t, *gpio_info_pt; + +static gpio_info_t gpio_ports_devs[] = { +#if defined(CONFIG_SOC_GPIO_32) + { .is_init = 0, + .reg_base = SOC_GPIO_BASE_ADDR, + .no_bits = SOC_GPIO_32_BITS, + .gpio_int_mask = INT_GPIO_MASK, + .vector = SOC_GPIO_INTERRUPT, + .gpio_cb = soc_gpio_32_cb, + .gpio_cb_arg = soc_gpio_32_arg, + .gpio_isr = gpio_isr }, +#endif +#if defined(CONFIG_SOC_GPIO_AON) + { .is_init = 0, + .reg_base = SOC_GPIO_AON_BASE_ADDR, + .no_bits = SOC_GPIO_AON_BITS, + .gpio_int_mask = INT_AON_GPIO_MASK, + .vector = SOC_GPIO_AON_INTERRUPT, + .gpio_cb = soc_gpio_aon_cb, + .gpio_cb_arg = soc_gpio_aon_arg, + .gpio_isr = gpio_aon_isr }, +#endif + }; + +void* soc_gpio_get_callback_arg(SOC_GPIO_PORT port_id, uint8_t pin) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return NULL; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + if (pin >= dev->no_bits) { + return NULL; + } + + return dev->gpio_cb_arg[pin]; +} + +DRIVER_API_RC soc_gpio_set_config(SOC_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config) +{ + DRIVER_API_RC ret; + uint32_t saved; + + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + + // Check if device is initialized + if(dev->is_init == 0) { + if((ret = soc_gpio_enable(port_id)) != DRV_RC_OK) { + return ret; + } + } + + // Check if pin is already in use + if((config->gpio_type == GPIO_INTERRUPT) && (dev->gpio_cb[bit] != NULL)) { + // pin is already in use + return DRV_RC_CONTROLLER_IN_USE; + } + + // Validate config data + if ((config->gpio_type != GPIO_INPUT) && (config->gpio_type != GPIO_OUTPUT) && (config->gpio_type != GPIO_INTERRUPT)) { + return DRV_RC_INVALID_CONFIG; + } + if ((config->int_type != LEVEL) && (config->int_type != EDGE) && (config->int_type != DOUBLE_EDGE)) { + return DRV_RC_INVALID_CONFIG; + } + + /* Disable Interrupts from this bit */ + CLEAR_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_INTEN), (uint32_t)bit); + + // Set interrupt handler to NULL + dev->gpio_cb[bit] = NULL; + dev->gpio_cb_arg[bit] = NULL; + + switch(config->gpio_type) + { + case GPIO_INPUT: + /* configure as input */ + CLEAR_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_SWPORTA_DDR), (uint32_t)bit); + break; + case GPIO_OUTPUT: + /* configure as output */ + SET_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_SWPORTA_DDR), (uint32_t)bit); + break; + case GPIO_INTERRUPT: + saved = interrupt_lock(); + // Configure interrupt handler + dev->gpio_cb[bit] = config->gpio_cb; + dev->gpio_cb_arg[bit] = config->gpio_cb_arg; + + /* Set as input */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_SWPORTA_DDR) &= ~(1 << bit); + + /* Set Level, Edge or Double Edge */ + if(config->int_type == LEVEL) { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTTYPE_LEVEL) &= ~(1 << bit); + } else if(config->int_type == EDGE) { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTTYPE_LEVEL) |= (1 << bit); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INT_BOTHEDGE) &= ~(1 << bit); + } else { // DOUBLE_EDGE + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTTYPE_LEVEL) |= (1 << bit); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INT_BOTHEDGE) |= (1 << bit); + } + + /* Set Polarity - Active Low / High */ + if(ACTIVE_LOW == config->int_polarity) { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTPOLARITY) &= ~(1 << bit); + } else { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTPOLARITY) |= (1 << bit); + } + + /* Set Debounce - On / Off */ + if(config->int_debounce == DEBOUNCE_OFF) { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_DEBOUNCE) &= ~(1 << bit); + } else { + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_DEBOUNCE) |= (1 << bit); + } + + /* Enable as Interrupt */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTEN) |= (1 << bit); + + /* Unmask Interrupt */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTMASK) &= ~(1 << bit); + + interrupt_unlock(saved); + break; + } + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_set_port_config(SOC_GPIO_PORT port_id, gpio_port_cfg_data_t *config) +{ + DRIVER_API_RC ret; + unsigned int i; + + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Check if device is initialized + if(dev->is_init == 0) { + if((ret = soc_gpio_enable(port_id)) != DRV_RC_OK) { + return ret; + } + } + + // Disable gpio interrupts + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTEN) = 0; + + for(i=0; ino_bits; i++) { + dev->gpio_cb[i] = config->gpio_cb[i]; + dev->gpio_cb_arg[i] = config->gpio_cb_arg[i]; + } + + // Set gpio direction + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_SWPORTA_DDR) = config->gpio_type; + // Set gpio interrupt settings + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTTYPE_LEVEL) = config->int_type; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTPOLARITY) = config->int_polarity; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_DEBOUNCE) = config->int_debounce; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_LS_SYNC) = config->int_ls_sync; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INT_BOTHEDGE) = config->int_bothedge; + + // Clear interrupt flag + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_PORTA_EOI) = (1<no_bits)-1; + // Enable gpio interrupt + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTMASK) = ~((~(config->gpio_type)) & (config->is_interrupt)); + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTEN) = ((~(config->gpio_type)) & (config->is_interrupt)); + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_deconfig(SOC_GPIO_PORT port_id, uint8_t bit) +{ + gpio_cfg_data_t config; + // Default configuration (input pin without interrupt) + config.gpio_type = GPIO_INPUT; + config.int_type = EDGE; + config.int_polarity = ACTIVE_LOW; + config.int_debounce = DEBOUNCE_OFF; + config.int_ls_sync = LS_SYNC_OFF; + config.gpio_cb = NULL; + config.gpio_cb_arg = NULL; + + return soc_gpio_set_config(port_id, bit, &config); +} + +DRIVER_API_RC soc_gpio_port_deconfig(SOC_GPIO_PORT port_id) +{ + unsigned int i; + gpio_port_cfg_data_t config; + + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Default configuration (input pin without interrupt) + config.gpio_type = 0; + config.is_interrupt = 0; + config.int_type = 0; + config.int_bothedge = 0; + config.int_polarity = 0; + config.int_debounce = 0; + config.int_ls_sync = 0; + + // TODO: use memset + for(i=0; ino_bits; i++) { + config.gpio_cb[i] = NULL; + config.gpio_cb_arg[i] = NULL; + } + + return soc_gpio_set_port_config(port_id, &config); +} + +DRIVER_API_RC soc_gpio_enable(SOC_GPIO_PORT port_id) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + /* enable peripheral clock */ + SET_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_LS_SYNC), (uint32_t)GPIO_CLKENA_POS); + SET_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_LS_SYNC), (uint32_t)GPIO_LS_SYNC_POS); + /* Clear any existing interrupts */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_PORTA_EOI) = ~(0); + /* enable interrupt for this GPIO block */ + SET_INTERRUPT_HANDLER(dev->vector, dev->gpio_isr); + /* Enable GPIO Interrupt into SSS */ + SOC_UNMASK_INTERRUPTS(dev->gpio_int_mask); + + dev->is_init = 1; + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_an_gpio_disable(SOC_GPIO_PORT port_id) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + /* Disable All Interrupts from port */ + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTEN) = 0; + /* disable peripheral clock */ + CLEAR_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_LS_SYNC), (uint32_t)GPIO_CLKENA_POS); + CLEAR_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_LS_SYNC), (uint32_t)GPIO_LS_SYNC_POS); + /* Disable GPIO Interrupt into SSS */ + MMIO_REG_VAL(dev->gpio_int_mask) |= DISABLE_SSS_INTERRUPTS; + + dev->is_init = 0; + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_write(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t value) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + /* read/modify/write bit */ + if (value) { + SET_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_SWPORTA_DR), (uint32_t)bit); + } else { + CLEAR_MMIO_BIT((volatile uint32_t *)(dev->reg_base+SOC_GPIO_SWPORTA_DR), (uint32_t)bit); + } + + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_write_port(SOC_GPIO_PORT port_id, uint32_t value) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_SWPORTA_DR) = value; + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_read(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t *value) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + + gpio_info_pt dev = &gpio_ports_devs[port_id]; + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + if (MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_SWPORTA_DDR) & (1 << bit)) { + return DRV_RC_INVALID_OPERATION; /* not configured as input */ + } + + *value = !!(MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_EXT_PORTA) & (1 << bit)); + return DRV_RC_OK; +} + +DRIVER_API_RC soc_gpio_read_port(SOC_GPIO_PORT port_id, uint32_t *value) +{ + // check port id + if(port_id >= SOC_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + *value = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_EXT_PORTA); + return DRV_RC_OK; +} + +static void soc_gpio_ISR_proc( uint32_t dev_id ) +{ + unsigned int i; + gpio_info_pt dev = &gpio_ports_devs[dev_id]; + + // Save interrupt status + uint32_t status = MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_INTSTATUS); + // Clear interrupt flag (write 1 to clear) + MMIO_REG_VAL_FROM_BASE(dev->reg_base, SOC_GPIO_PORTA_EOI) = status; + + for (i=0; ino_bits; i++) { + if ((status & (1 << i)) && (dev->gpio_cb[i])) { + (dev->gpio_cb[i])(status, dev->gpio_cb_arg[i]); + } + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/system/libarc32_edu/drivers/soc_gpio.h b/system/libarc32_edu/drivers/soc_gpio.h new file mode 100644 index 00000000..86976748 --- /dev/null +++ b/system/libarc32_edu/drivers/soc_gpio.h @@ -0,0 +1,234 @@ +/** INTEL CONFIDENTIAL Copyright 2014-2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef SOC_GPIO_H_ +#define SOC_GPIO_H_ + +/** + * \addtogroup common_drivers + * @{ + * \defgroup soc_gpio SOC GPIO: General Purpose Input/Output API + * @{ + * \brief Definition of the structure and functions used by SOC GPIO Driver implementation. + */ + +#if defined(CONFIG_SOC_GPIO_32) || defined(CONFIG_SOC_GPIO_AON) + +#include "data_type.h" +#include "gpio.h" + +// soc gpio 32 bit count +#if defined(CONFIG_SOC_GPIO_32) +#define SOC_GPIO_32_BITS (32) +#endif + +// soc gpio aon bit count +#if defined(CONFIG_SOC_GPIO_AON) +#define SOC_GPIO_AON_BITS (6) +#endif + +/*! + * Port list + */ +typedef enum { +#if defined(CONFIG_SOC_GPIO_32) + SOC_GPIO_32=0, /*!< GPIO 32 port */ + #if defined(CONFIG_SOC_GPIO_AON) + SOC_GPIO_AON, /*!< GPIO aon port */ + #endif +#elif defined(CONFIG_SOC_GPIO_AON) + SOC_GPIO_AON=0, /*!< GPIO aon port */ +#endif + SOC_PORT_COUNT /*!< GPIO port count */ +} SOC_GPIO_PORT; + + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn DRIVER_API_RC soc_gpio_set_config(SOC_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config) +* +* \brief Function to configure specified GPIO bit in specified GPIO port +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param config : pointer to configuration structure +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_set_config(SOC_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config); + +/*! \fn DRIVER_API_RC soc_gpio_set_port_config(SOC_GPIO_PORT port_id, soc_gpio_cfg_data_t *config) +* +* \brief Function to configure specified GPIO port (in LMT case the selection is ignored - only one port) +* +* \param port_id : GPIO port identifier +* \param config : pointer to configuration structure +* +* \return RC_OK on success +* RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller +* RC_INVALID_CONFIG - if any configuration parameters are not valid +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_set_port_config(SOC_GPIO_PORT port_id, gpio_port_cfg_data_t *config); + +/*! \fn DRIVER_API_RC soc_gpio_deconfig(SOC_GPIO_PORT port_id, uint8_t bit) +* +* \brief Function to deconfigure specified GPIO bit in specified GPIO port +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to deconfigure +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_deconfig(SOC_GPIO_PORT port_id, uint8_t bit); + +/*! \fn DRIVER_API_RC soc_gpio_port_deconfig(SOC_GPIO_PORT port_id) +* +* \brief Function to deconfigure specified specified GPIO port +* +* \param port_id : GPIO port identifier +* +* \return RC_OK on success +* RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_port_deconfig(SOC_GPIO_PORT port_id); + +/*! \fn void* soc_gpio_get_callback_arg(SOC_GPIO_PORT port_id, uint8_t pin) +* +* \brief Function to get callback argument pointer for a specific pin +* +* \param port_id : GPIO port identifier +* \param bit : pin in port to configure +* +* \return ptr if success else NULL +*/ +void* soc_gpio_get_callback_arg(SOC_GPIO_PORT port_id, uint8_t pin); + +/*! \fn DRIVER_API_RC soc_gpio_enable(SOC_GPIO_PORT port_id) +* +* \brief Function to enable the specified GPIO port +* Upon success, the specified GPIO port is no longer clock gated in hardware, it is now +* capable of reading and writing GPIO bits and of generating interrupts. +* +* \param port_id : GPIO port identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_enable(SOC_GPIO_PORT port_id); + +/*! \fn DRIVER_API_RC soc_gpio_disable(SOC_GPIO_PORT port_id) +* +* \brief Function to disable the specified GPIO port +* Upon success, the specified GPIO port is clock gated in hardware, it is now +* incapable of reading, writing GPIO bits and of generating interrupts. +* +* \param port_id : GPIO port identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_disable(SOC_GPIO_PORT port_id); + +/*! \fn DRIVER_API_RC soc_gpio_write(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t value) +* +* \brief Function to set output value on the gpio bit +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param value : value to write to bit +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_write(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t value); + + +/*! \fn DRIVER_API_RC soc_gpio_read(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t *value) +* +* \brief Function to read a GPIO bit +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param *value : address to place read value +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_read(SOC_GPIO_PORT port_id, uint8_t bit, boolean_t *value); + +/*! \fn DRIVER_API_RC soc_gpio_write_port(SOC_GPIO_PORT port_id, uint32_t value) +* +* \brief Function to write to a value to a given port +* +* \param port_id : GPIO port identifier +* \param value : value to write to port +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_write_port(SOC_GPIO_PORT port_id, uint32_t value); + +/*! \fn DRIVER_API_RC soc_gpio_read_port(SOC_GPIO_PORT port_id, uint32_t *value) +* +* \brief Function to read a given port +* +* \param port_id : GPIO port identifier +* \param *value : location to store result +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC soc_gpio_read_port(SOC_GPIO_PORT port_id, uint32_t *value); + +#ifdef __cplusplus +} +#endif + +#endif +#endif /* SOC_GPIO_H_ */ + +/**@} @}*/ diff --git a/system/libarc32_edu/drivers/soc_spi_priv.h b/system/libarc32_edu/drivers/soc_spi_priv.h new file mode 100644 index 00000000..4a30f16d --- /dev/null +++ b/system/libarc32_edu/drivers/soc_spi_priv.h @@ -0,0 +1,171 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + /* + * Intel SOC SPI driver + * + */ +#ifndef SOC_SPI_PRIV_H_ +#define SOC_SPI_PRIV_H_ + +#include "data_type.h" + +/* SPI software configs */ +#define SPI_TX_FIFO_THRESHOLD (7) +#define SPI_RX_FIFO_THRESHOLD (0) + +/* SPI FIFO Size */ +#define IO_SPI_MST0_FS (8) +#define IO_SPI_MST1_FS (8) +#define IO_SPI_SLV_FS (8) + +/* Chip-Select and GPIO lookup */ +#define SPIM0_CS_1_GPIO24 (24) +#define SPIM0_CS_2_GPIO25 (25) +#define SPIM0_CS_3_GPIO26 (26) +#define SPIM0_CS_4_GPIO27 (27) + +/* SoC SPI device register offsets */ +#define CTRL0 (0x00) /* SoC SPI Control Register 1 */ +#define CTRL1 (0x04) /* SoC SPI Control Register 2 */ +#define SPIEN (0x08) /* SoC SPI Enable Register */ +#define SER (0x10) /* SoC SPI Slave Enable Register */ +#define BAUDR (0x14) /* SoC SPI Baud Rate Select */ +#define TXFTL (0x18) /* SoC SPI Transmit FIFO Threshold Level */ +#define RXFTL (0x1C) /* SoC SPI Receive FIFO Threshold Level */ +#define TXFL (0x20) /* SoC SPI Transmit FIFO Level Register */ +#define RXFL (0x24) /* SoC SPI Receive FIFO Level Register */ +#define SR (0x28) /* SoC SPI Status Register */ +#define IMR (0x2C) /* SoC SPI Interrupt Mask Register */ +#define ISR (0x30) /* SoC SPI Interrupt Status Register */ +#define RISR (0x34) /* SoC SPI Raw Interrupt Status Register */ +#define TXFOIC (0x38) /* SoC SPI TX FIFO Overflow Interrupt Clear */ +#define RXFOIC (0x3C) /* SoC SPI RX FIFO Overflow Interrupt Clear */ +#define RXFUIC (0x40) /* SoC SPI TX FIFO Underflow Interrupt Clear */ +#define MMIC (0x44) /* SoC SPI Multi Master Interrupt Clear */ +#define ICR (0x48) /* SoC SPI TX Interrupt Clear Register */ +#define IDR (0x58) /* SoC SPI Identification Register */ +#define DR (0x60) /* SoC SPI Data Register */ + +/* SPI specific macros */ +#define SPI_ENABLE_INT (0x1f) /* Enable SoC SPI Interrupts */ +#define SPI_ENABLE_RX_INT (0x10) /* Enable SoC SPI RX Interrupts */ +#define SPI_ENABLE_TX_INT (0x01) /* Enable SoC SPI TX Interrupts */ +#define SPI_DISABLE_TX_INT (~0x00000001) /* Disable TX FIFO Empty interrupts */ +#define SPI_DISABLE_INT (0x0) /* Disable SoC SPI Interrupts */ +#define SPI_STATUS_RFF (0x10) /* RX FIFO Full */ +#define SPI_STATUS_TFE (0x4) /* TX FIFO Empty */ +#define SPI_STATUS_TFNF (0x2) /* TX FIFO not full */ +#define SPI_STATUS_RFNE (0x1 << 3) /* RX FIFO not empty */ +#define SPI_STATUS_BUSY (0x1) /* Busy status */ +#define SPI_POP_DATA (0x80000000) /* Dummy data */ +#define SPI_PUSH_DATA (0xc0000000) /* Dummy data */ +#define SPI_ENABLE (0x1) /* Enable SoC SPI Device */ +#define SPI_DISABLE (0x0) /* Disable SoC SPI Device */ +#define SPI_TX_INT (0x1) /* SoC SPI TX Interrupt */ +#define SPI_RX_INT (0x10) /* SoC SPI RX Interrupt */ +#define SPI_TXE (0x1 << 5) /* Transmission Error */ +#define SPI_SLAVE_OD (0x1 << 10) /* Slave output disable */ +#define SPI_SLAVE_OE ~(SPI_SLAVE_OD) /* Slave output enable */ + +#define ENABLE_SOC_SPI_INTERRUPTS (~0x1 << 8) +#define ENABLE_SPI_MASTER_0 (0x1 << 14) +#define ENABLE_SPI_MASTER_1 (0x1 << 15) +#define ENABLE_SPI_SLAVE (0x1 << 16) +#define DISABLE_SPI_MASTER_0 (~ENABLE_SPI_MASTER_0) +#define DISABLE_SPI_MASTER_1 (~ENABLE_SPI_MASTER_1) +#define DISABLE_SPI_SLAVE (~ENABLE_SPI_SLAVE) + +/* SPI device states */ +#define SPI_STATE_CLOSED (0) +#define SPI_STATE_DISABLED (1) +#define SPI_STATE_IDLE (2) +#define SPI_STATE_TRANSMIT (3) +#define SPI_STATE_RECEIVE (4) +#define SPI_STATE_SLAVE_FD (5) /* Full duplex slave mode */ + +#define BAUD_DIVISOR 1000 + +typedef enum +{ + NORMAL_MODE = 0, + TEST_MODE /* Test mode used for loopback testing */ +}SHIFT_REG_LOOP; + +/*! Enables tracking of which setup function is called first - necessary + * when enabling interrupts */ +typedef enum +{ + UNASSIGNED = 0, + RX_FIRST, + TX_FIRST, +}SLAVE_FULL_DUPLEX_ORDER; + + +typedef void (*SPI_ISR) (); +typedef void (* IO_CB_FUNC)( uint32_t ); + + +typedef struct { + IO_CB_FUNC cb; +} io_cb_t; + +/* Private data structure maintained by the driver. */ +typedef struct soc_spi_info_struct +{ + uint32_t reg_base; /* base address of device register set */ + /* TX & RX Buffer and lengths */ + uint32_t tx_len; + uint32_t rx_len; + uint32_t tx_count; + uint32_t rx_count; + uint32_t discarded; + uint32_t dummy_tx; + uint8_t * tx_buf; + uint8_t * rx_buf; + uint16_t * rx_buf_16; + uint8_t state; + uint8_t mode; + uint8_t cs_gpio; + uint8_t instID; + uint8_t full_duplex; + SLAVE_FULL_DUPLEX_ORDER fd_order; + /* Data frame Size */ + uint8_t dfs; + /* Callbacks */ + IO_CB_FUNC xfer_cb; + uint32_t cb_xfer_data; + IO_CB_FUNC err_cb; + uint32_t cb_err_data; + IO_CB_FUNC slave_rx_cb; + /* Interrupt numbers and handlers */ + uint8_t isr_vector; /* ISR vectors */ + SPI_ISR isr; /* SPI device ISR */ + uint16_t fifo_depth; + /* Interrupt Routing Mask Registers */ + uint32_t spi_int_mask; +} soc_spi_info_t, *soc_spi_info_pt; + +void soc_spi_ISR_proc( soc_spi_info_pt dev ); + +#endif /* SOC_SPI_PRIV_H_ */ diff --git a/system/libarc32_edu/drivers/ss_adc_iface.c.old b/system/libarc32_edu/drivers/ss_adc_iface.c.old new file mode 100644 index 00000000..add3b6fe --- /dev/null +++ b/system/libarc32_edu/drivers/ss_adc_iface.c.old @@ -0,0 +1,382 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#include +#include +#include "data_type.h" +#include "ss_adc_iface.h" +#include "soc_register.h" +#include "io_config.h" +#include "eiaextensions.h" +#include "adc_priv.h" +#include "ss_dw_adc.h" +#include "portable.h" + +#define ADC_MAX_CNT (1) +#define ADC_SS_NUM_CONTROLLERS (1) + +#define ADC_CLOCK_GATE (1 << 31) +#define ADC_STANDBY ( 0x02 ) +#define ADC_NORMAL_WO_CALIB ( 0x04 ) +#define ADC_MODE_MASK ( 0x07 ) + +#define ONE_BIT_SET (0x1) +#define FIVE_BITS_SET (0x1f) +#define SIX_BITS_SET (0x3f) +#define ELEVEN_BITS_SET (0x7ff) + +#define INPUT_MODE_POS (5) +#define CAPTURE_MODE_POS (6) +#define OUTPUT_MODE_POS (7) +#define SERIAL_DELAY_POS (8) +#define SEQUENCE_MODE_POS (13) +#define SEQ_ENTRIES_POS (16) +#define THRESHOLD_POS (24) + +#define SEQ_DELAY_EVEN_POS (5) +#define SEQ_MUX_ODD_POS (16) +#define SEQ_DELAY_ODD_POS (21) + +#ifdef __cplusplus + extern "C" { +#endif + +static void copy_config_data(ss_adc_cfg_data_t *cfg); +static void adc_goto_normal_mode_wo_calibration(void); +static void adc_goto_deep_power_down(void); + +DECLARE_INTERRUPT_HANDLER static void adc0_rx_ISR(); +DECLARE_INTERRUPT_HANDLER static void adc0_err_ISR(); + +/* ADC devices private data structures */ +adc_info_pt adc_handles[ADC_MAX_CNT] = { 0 }; + +adc_info_t adc_devs[] = { + { .instID = 0, + .reg_base = AR_IO_ADC0_SET, + .rx_vector = IO_ADC0_INT_IRQ, + .err_vector = IO_ADC0_INT_ERR, + .rx_isr = adc0_rx_ISR, + .err_isr = adc0_err_ISR, + .fifo_tld = IO_ADC0_FS/2, + .adc_irq_mask = SCSS_REGISTER_BASE + INT_SS_ADC_IRQ_MASK, + .adc_err_mask = SCSS_REGISTER_BASE + INT_SS_ADC_ERR_MASK }, + { .instID = ADC_MAX_CNT } + }; + +DECLARE_INTERRUPT_HANDLER static void adc0_rx_ISR() +{ + adc_rx_ISR_proc(adc_handles[0]); +} +DECLARE_INTERRUPT_HANDLER static void adc0_err_ISR() +{ + adc_err_ISR_proc(adc_handles[0]); +} + +ss_adc_cfg_data_t drv_config[ADC_SS_NUM_CONTROLLERS]; + +/*! \fn void ss_adc_set_config(ss_adc_cfg_data_t *config) +* +* \brief Function to configure specified ADC controller +* +* \param config : pointer to configuration structure +* +*/ +void ss_adc_set_config(ss_adc_cfg_data_t *config) +{ + adc_info_pt dev = &adc_devs[0]; + uint32_t reg_val = 0, val = 0, ctrl = 0; + ss_adc_cfg_data_t *cfg = &drv_config[0]; + + adc_handles[0] = dev; + + copy_config_data(config); + + ctrl = ADC_INT_DSB|ADC_CLK_ENABLE; + REG_WRITE( ADC_CTRL, ctrl ); + + /* set sample width, input mode, output mode and serial delay */ + reg_val = READ_ARC_REG(dev->reg_base+ ADC_SET ); + reg_val &= ADC_CONFIG_SET_MASK; + val = (cfg->sample_width) & FIVE_BITS_SET; + val |= ((cfg->in_mode & ONE_BIT_SET) << INPUT_MODE_POS); + val |= ((cfg->capture_mode & ONE_BIT_SET) << CAPTURE_MODE_POS); + val |= ((cfg->out_mode & ONE_BIT_SET) << OUTPUT_MODE_POS); + val |= ((cfg->serial_dly & FIVE_BITS_SET) << SERIAL_DELAY_POS); + /* TODO: add cfg->seq_mode on next line when we'll support it */ + val |= ((0x0 & ONE_BIT_SET) << SEQUENCE_MODE_POS); + REG_WRITE( ADC_SET, reg_val|val ); + + dev->rx_len = 0; + /* TODO: add IO_ADC_SEQ_MODE_REPETITIVE support here later and adjust + * seq_size accordingly. */ + dev->seq_mode = IO_ADC_SEQ_MODE_SINGLESHOT; + dev->seq_size = 1; + dev->state = ADC_STATE_IDLE; + + /* set clock ratio */ + REG_WRITE( ADC_DIVSEQSTAT, cfg->clock_ratio & ADC_CLK_RATIO_MASK ); + + /* user callbacks */ + dev->err_cb = cfg->cb_err; + dev->rx_cb = cfg->cb_rx; + + + /* disable clock once setup done */ + REG_WRITE( ADC_CTRL, ADC_INT_ENABLE & ~(ADC_CLK_ENABLE) ); + + /* set interrupt vector, mid/high priority */ + SET_INTERRUPT_HANDLER( dev->rx_vector, dev->rx_isr ); + SET_INTERRUPT_HANDLER( dev->err_vector, dev->err_isr ); + + /* + * SoC ADC config + */ + /* Setup ADC Interrupt Routing Mask Registers to allow interrupts through */ + MMIO_REG_VAL(dev->adc_irq_mask) &= ENABLE_SSS_INTERRUPTS; + MMIO_REG_VAL(dev->adc_err_mask) &= ENABLE_SSS_INTERRUPTS; +} + +/*! \fn void ss_adc_enable(void) +* +* \brief Function to enable the specified ADC controller +* Upon success, the specified ADC interface is no longer clock gated in hardware, it is now +* capable of sampling channel data and of generating interrupts. +*/ +void ss_adc_enable(void) +{ + adc_info_pt dev = &adc_devs[0]; + + adc_goto_normal_mode_wo_calibration(); + /* Enable adc clock and reset sequence pointer */ + REG_WRITE( ADC_CTRL, ADC_INT_ENABLE | ADC_CLK_ENABLE | ADC_SEQ_TABLE_RST ); + dev->state = ADC_STATE_IDLE; + +} + +/*! \fn void ss_adc_disable(void) +* +* \brief Function to disable the specified ADC controller. +* +*/ +void ss_adc_disable(void) +{ + adc_info_pt dev = &adc_devs[0]; + uint32_t saved; + + adc_goto_deep_power_down(); + REG_WRITE( ADC_CTRL, ADC_INT_DSB|ADC_SEQ_PTR_RST ); + + /* Protect ADC_SET using lock and unlock of interruptions */ + saved = interrupt_lock(); + /* TODO sak should we do this on disable ?? */ + WRITE_ARC_REG(READ_ARC_REG(dev->reg_base+ADC_SET) | ADC_FLUSH_RX, + dev->reg_base+ADC_SET); + interrupt_unlock(saved); + + dev->state = ADC_STATE_DISABLED; +} + + +/*! \fn void ss_adc_read(io_adc_seq_table_t *seq_tbl, + * uint8_t *data, uint32_t data_len, + * uint32_t *actual_data_len, + * uint32_t *status_code) +* +* \brief Read samples from ADC according to sequence table config +* \param data : pointer to buffer to store data +* \param data_len : length of data to read +* \param actual_data_len : pointer to value that is updated with actual length of data read +* \param status_code : if DRV_RC_FAIL is returned - this holds the status/reason code +* +*/ + +DRIVER_API_RC ss_adc_read(io_adc_seq_table_t *seq_tbl, uint32_t *data, + uint32_t data_len, uint32_t *actual_data_len, + uint32_t *status_code) +{ + adc_info_pt dev = &adc_devs[0]; + uint32_t ctrl = 0, reg_val = 0; + uint32_t i = 0, num_iters = 0; + io_adc_seq_entry_t *entry = NULL; + uint32_t saved; + + if( ADC_STATE_IDLE != dev->state ) + return DRV_RC_CONTROLLER_IN_USE; + + + /* Protect ADC_SET and ADC_CTRL using lock and unlock of interruptions */ + saved = interrupt_lock(); + + /* Reset Sequence Pointer */ + ctrl = READ_ARC_REG(dev->reg_base+ADC_CTRL); + ctrl |= ADC_SEQ_PTR_RST; + WRITE_ARC_REG(ctrl, (dev->reg_base+ADC_CTRL)); + + /* Setup sequence table */ + dev->seq_size = seq_tbl->num_entries; + + reg_val = READ_ARC_REG(dev->reg_base+ADC_SET); + reg_val &= ADC_SEQ_SIZE_SET_MASK; + reg_val |= ( ((seq_tbl->num_entries - 1) & SIX_BITS_SET) << SEQ_ENTRIES_POS ); + reg_val |= ((dev->seq_size - 1) << THRESHOLD_POS ); + WRITE_ARC_REG(reg_val, dev->reg_base+ADC_SET); + + interrupt_unlock(saved); + + num_iters = seq_tbl->num_entries/2; + + for( i = 0, entry = seq_tbl->entries; + i < num_iters; + i++, entry += 2 ) + { + reg_val = ((entry[1].sample_dly & ELEVEN_BITS_SET) << SEQ_DELAY_ODD_POS); + reg_val |= ((entry[1].channel_id & FIVE_BITS_SET) << SEQ_MUX_ODD_POS); + reg_val |= ((entry[0].sample_dly & ELEVEN_BITS_SET) << SEQ_DELAY_EVEN_POS); + reg_val |= (entry[0].channel_id & FIVE_BITS_SET); + REG_WRITE( ADC_SEQ, reg_val ); + } + if( 0 != (seq_tbl->num_entries % 2) ) + { + reg_val = ((entry[0].sample_dly & ELEVEN_BITS_SET) << SEQ_DELAY_EVEN_POS); + reg_val |= (entry[0].channel_id & FIVE_BITS_SET); + REG_WRITE( ADC_SEQ, reg_val ); + } + REG_WRITE( ADC_CTRL, ctrl | ADC_SEQ_PTR_RST ); + + if( ADC_STATE_IDLE == dev->state ) + { + for( i = 0; i < BUFS_NUM; i++ ) + { + dev->rx_buf[i] = NULL; + } + dev->rx_buf[0] = data; + dev->rx_len = data_len; + dev->res_size[0] = actual_data_len; + *( dev->res_size[0] ) = 0; + dev->index = 0; + dev->state = ADC_STATE_SAMPLING; + /* enable AD converter, start sequencer */ + REG_WRITE( ADC_CTRL, ADC_SEQ_START|ADC_ENABLE|ADC_CLK_ENABLE ); + } + else if( IO_ADC_SEQ_MODE_REPETITIVE == dev->seq_mode ) + { + uint32_t idx = dev->index; + + if( NULL == dev->rx_buf[idx] ) + { + dev->rx_buf[idx] = data; + dev->rx_len = data_len; + dev->res_size[idx] = actual_data_len; + *( dev->res_size[idx] ) = 0; + } + } + return DRV_RC_OK; +} +/* + * Function to put the ADC controller into a working state. + */ + +static void adc_goto_normal_mode_wo_calibration(void) +{ + uint32_t creg; + uint32_t saved; + + // read creg slave to get current Power Mode + creg = _lr(AR_IO_CREG_SLV0_OBSR); + + // perform power up to "Normal mode w/o calibration" cycle if not already there + if( (creg & ADC_MODE_MASK) != ADC_NORMAL_WO_CALIB){ + + /* Protect AR_IO_CREG_MST0_CTRL using lock and unlock of interruptions */ + saved = interrupt_lock(); + // Read current CREG master + creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL); + creg &= ~(ADC_MODE_MASK); + // request ADC to go to Standby mode + creg |= ADC_STANDBY | ADC_CLOCK_GATE; + WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL); + interrupt_unlock(saved); + + // Poll CREG Slave 0 for Power Mode status = requested status + while ( (creg = _lr(AR_IO_CREG_SLV0_OBSR) & 0x8) == 0); + + /* Protect AR_IO_CREG_MST0_CTRL using lock and unlock of interruptions */ + saved = interrupt_lock(); + creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL); + creg &= ~(ADC_MODE_MASK); + // request ADC to go to Normal mode w/o calibration + creg |= ADC_NORMAL_WO_CALIB | ADC_CLOCK_GATE; + WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL); + interrupt_unlock(saved); + + // Poll CREG Slave 0 for Power Mode status = requested status + while ( ((creg = _lr(AR_IO_CREG_SLV0_OBSR)) & 0x8) == 0); + } +} +static void adc_goto_deep_power_down(void) +{ + uint32_t creg; + uint32_t saved; + + // read creg slave to get current Power Mode + creg = _lr(AR_IO_CREG_SLV0_OBSR); + // perform cycle down to "Deep Power Down mode" if not already there + if( (creg & ADC_MODE_MASK) != 0){ + + /* Protect AR_IO_CREG_MST0_CTRL using lock and unlock of interruptions */ + saved = interrupt_lock(); + + // Read current CREG master + creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL); + creg &= ~(ADC_MODE_MASK); + // request ADC to go to Deep Power Down mode + creg |= 0 | ADC_CLOCK_GATE; + WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL); + interrupt_unlock(saved); + + // Poll CREG Slave 0 for Power Mode status = requested status + while ( ((creg = _lr(AR_IO_CREG_SLV0_OBSR)) & 0x8) == 0); + } +} + + +static void copy_config_data(ss_adc_cfg_data_t *cfg) +{ + /* copy passed in config data locally */ + drv_config[0].capture_mode = cfg->capture_mode; + drv_config[0].cb_err = cfg->cb_err; + drv_config[0].cb_err_data = cfg->cb_err_data; + drv_config[0].cb_rx = cfg->cb_rx; + drv_config[0].cb_rx_data = cfg->cb_rx_data; + drv_config[0].in_mode = cfg->in_mode; + drv_config[0].out_mode = cfg->out_mode; + drv_config[0].sample_width = cfg->sample_width; + drv_config[0].serial_dly = cfg->serial_dly; + drv_config[0].clock_ratio = cfg->clock_ratio; +} + +#ifdef __cplusplus +} +#endif diff --git a/system/libarc32_edu/drivers/ss_adc_iface.h b/system/libarc32_edu/drivers/ss_adc_iface.h new file mode 100644 index 00000000..fd110c77 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_adc_iface.h @@ -0,0 +1,181 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +/** + * \defgroup arc_driver ARC Drivers + * \brief Definition of the structure and functions used by ARC drivers implementation. + * + * It consists of: + * - ARC Drivers APIs + * + * @{ + */ + + +/** + * \addtogroup arc_driver + * @{ + * \defgroup adc_arc_driver ADC: Analog/Digital Converter API + * @{ + * \brief Definition of the structure and functions used by ADC ARC Driver implementation. + */ + + +#ifndef SS_ADC_IFACE_H_ +#define SS_ADC_IFACE_H_ + + +typedef enum { + SINGLED_ENDED = 0, + DIFFERENTIAL = 1 +} INPUT_MODE; + +typedef enum { + PARALLEL = 0, + SERIAL = 1 +} OUTPUT_MODE; + + +typedef enum { + RISING_EDGE = 0, + FALLING_EDGE = 1 +} CAPTURE_MODE; + +typedef enum { + WIDTH_6_BIT = 0x0, + WIDTH_8_BIT = 0x1, + WIDTH_10_BIT = 0x2, + WIDTH_12_BIT = 0x3 +} SAMPLE_WIDTH; + + +/*! +* \brief callback function signature +*/ +typedef void (*adc_callback)( uint32_t ); /*!< callback function signature */ + +/* Structure representing AD converter configuration */ +typedef struct +{ + INPUT_MODE in_mode; /*!< ADC input mode: single ended or differential */ + OUTPUT_MODE out_mode; /*!< ADC output mode: parallel or serial */ + uint8_t serial_dly; /*!< Number of adc_clk the first bit of serial output is delayed for after start of conversion */ + CAPTURE_MODE capture_mode; /*!< ADC controller capture mode: by rising or falling edge of adc_clk */ + SAMPLE_WIDTH sample_width; /*!< ADC sample width */ + uint32_t clock_ratio; /*!< TODO */ + adc_callback cb_rx; /*!< callback function for notification of data received and available to application, NULL if callback not required by application code */ + uint32_t cb_rx_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ + adc_callback cb_err; /*!< callback function on transaction error, NULL if callback not required by application code */ + uint32_t cb_err_data; /*!< this will be passed back by the callback routine - can be used as an controller identifier */ +} ss_adc_cfg_data_t; + +/* simple macro to convert resolution to sample width to be used in the + * configuration structure. It converts from 6,8,10,12 to 0x0,0x01,0x2,0x3 + */ +#define ss_adc_res_to_sample_width(_res_) ((SAMPLE_WIDTH)(((_res_-6)/2) & 0x3)) +#define ADC_VREF 3300 /* mV = 3.3V */ +/* result in mV is given by converting raw data: + * result = (data * ADC_VREF) / (2^resolution) + */ +#define ss_adc_data_to_mv(_data_, _resolution_) \ + ((_data_ * ADC_VREF) / (1 << _resolution_)) + +/* Structure representing ADC sequence table entry. */ +typedef struct +{ + uint32_t sample_dly; /*!< delay to be introduced prior to start of conversion, in terms of adc clocks */ + uint8_t channel_id; /*!< ADC input associated with the entry */ +} io_adc_seq_entry_t; + + +/* Structure representing ADC sequence table. */ +typedef struct +{ + io_adc_seq_entry_t *entries; + uint8_t num_entries; +} io_adc_seq_table_t; + + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn void ss_adc_set_config(ss_adc_cfg_data_t *config) +* +* \brief Function to configure ADC controller +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param config : pointer to configuration structure +* +*/ +void ss_adc_set_config(ss_adc_cfg_data_t *config); + + +/*! \fn void ss_adc_enable(void) +* +* \brief Function to enable the ADC controller +* Upon success, the ADC interface is no longer clock gated in hardware, it is now +* TODO capable of transmitting and receiving on the ADC bus and of generating interrupts. +* +*/ +void ss_adc_enable(void); + + +/*! \fn void ss_adc_disable(void) +* +* \brief Function to disable the ADC controller. +* Upon success, the ADC interface is clock gated in hardware, +* it is no longer capable of generating interrupts. +* +*/ +void ss_adc_disable(void); + + +/*! \fn void ss_adc_read(io_adc_seq_table_t * seq_tbl, uint32_t *data, + uint32_t data_len, uint32_t *actual_data_len, + uint32_t *status_code); +* +* \brief Function to read samples from the ADC +* +* \param seq_tbl : pointer to io_adc_seq_table +* \param data : buffer for sampling output +* \param data_len : size of data to be read +* \param actual_data_len : size of data actually read +* \param status_code : sampling status code +* +* \return DRV_RC_OK on success\n +* DRV_RC_CONTROLLER_IN_USE, if ADC is already sampling\n +*/ + +DRIVER_API_RC ss_adc_read(io_adc_seq_table_t * seq_tbl, uint32_t *data, + uint32_t data_len, uint32_t *actual_data_len, + uint32_t *status_code); + +#ifdef __cplusplus +} +#endif + +#endif /* SS_ADC_IFACE_H_ */ + +/**@} @} @}*/ diff --git a/system/libarc32_edu/drivers/ss_dw_adc.h b/system/libarc32_edu/drivers/ss_dw_adc.h new file mode 100644 index 00000000..e82b8028 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_dw_adc.h @@ -0,0 +1,27 @@ +/* +* +* CONFIDENTIAL AND PROPRIETARY INFORMATION +* +* Copyright (c) 2013 Synopsys, Inc. All rights reserved. +* This software and documentation contain confidential and +* proprietary information that is the property of +* Synopsys, Inc. The software and documentation are +* furnished under a license agreement and may be used +* or copied only in accordance with the terms of the license +* agreement. No part of the software and documentation +* may be reproduced, transmitted, or translated, in any +* form or by any means, electronic, mechanical, manual, +* optical, or otherwise, without prior written permission +* of Synopsys, Inc., or as expressly provided by the license agreement. +* Reverse engineering is prohibited, and reproduction, +* disclosure or use without specific written authorization +* of Synopsys Inc. is strictly forbidden. +*/ +#ifndef SS_DW_ADC_H_ +#define SS_DW_ADC_H_ + + +void adc_rx_ISR_proc( adc_info_pt dev ); +void adc_err_ISR_proc( adc_info_pt dev ); + +#endif /* SS_DW_ADC_H_ */ diff --git a/system/libarc32_edu/drivers/ss_dw_i2c.c b/system/libarc32_edu/drivers/ss_dw_i2c.c new file mode 100644 index 00000000..7c7a79b7 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_dw_i2c.c @@ -0,0 +1,227 @@ +/* +* +* CONFIDENTIAL AND PROPRIETARY INFORMATION +* +* Copyright (c) 2013 Synopsys, Inc. All rights reserved. +* This software and documentation contain confidential and +* proprietary information that is the property of +* Synopsys, Inc. The software and documentation are +* furnished under a license agreement and may be used +* or copied only in accordance with the terms of the license +* agreement. No part of the software and documentation +* may be reproduced, transmitted, or translated, in any +* form or by any means, electronic, mechanical, manual, +* optical, or otherwise, without prior written permission +* of Synopsys, Inc., or as expressly provided by the license agreement. +* Reverse engineering is prohibited, and reproduction, +* disclosure or use without specific written authorization +* of Synopsys Inc. is strictly forbidden. +*/ + + +#include "data_type.h" +#include "i2c_priv.h" +#include "ss_dw_i2c.h" +#include "soc_register.h" + +static void end_data_transfer (i2c_info_pt dev) +{ + uint32_t state; + REG_WRITE( I2C_INTR_MASK, I2C_INT_DSB ); + state = dev->state; + dev->state = I2C_STATE_READY; + if ( I2C_STATE_RECEIVE == state ) + { + if( _Usually( NULL != dev->rx_cb ) ) + { + dev->rx_cb( dev->cb_rx_data ); + } + } + else if ( I2C_STATE_TRANSMIT == state ) + { + if( _Usually( NULL != dev->tx_cb ) ) + { + dev->tx_cb( dev->cb_tx_data ); + } + } +} + + +static void recv_data(i2c_info_pt dev) +{ + uint32_t i, rx_cnt = 0; + + + if (_Rarely(!dev->rx_len)) + { + return; + } + + rx_cnt = REG_READ( I2C_RXFLR ); + + if (rx_cnt > dev->rx_len) + { + rx_cnt = dev->rx_len; + } + for (i = 0; i < rx_cnt; i++) + { + REG_WRITE( I2C_DATA_CMD, I2C_POP_DATA ); + _nop(); + dev->i2c_read_buff[i] = REG_READ( I2C_DATA_CMD ); + } + dev->i2c_read_buff += i; + dev->rx_len -= i; + dev->total_read_bytes += i; +} + + +void i2c_fill_fifo(i2c_info_pt dev) +{ + uint32_t i, tx_cnt, data; + if (_Rarely(!dev->rx_tx_len)) + { + return; + } + + tx_cnt = dev->fifo_depth - REG_READ( I2C_TXFLR ); + if (tx_cnt > dev->rx_tx_len) + { + tx_cnt = dev->rx_tx_len; + } + + for (i = 0; i < tx_cnt; i++) + { + if (dev->tx_len > 0){ // something to transmit + data = I2C_PUSH_DATA | dev->i2c_write_buff[i]; + + if( dev->tx_len == 1) + { // last byte to write + if (dev->rx_len > 0) // repeated start if something to read after + data |= I2C_RESTART_CMD; + else + data |= I2C_STOP_CMD; + } + dev->tx_len -= 1; + dev->total_write_bytes += 1; + } + else + { // something to read + data = I2C_PUSH_DATA | I2C_READ_CMD; + if (dev->rx_tx_len == 1) // last dummy byte to write + data |= I2C_STOP_CMD; + } + REG_WRITE( I2C_DATA_CMD, data ); + dev->rx_tx_len -= 1; + } + dev->i2c_write_buff += i; +} + +static void xmit_data(i2c_info_pt dev) +{ + int mask; + i2c_fill_fifo(dev); + if (dev->rx_tx_len <= 0) + { + mask = REG_READ( I2C_INTR_MASK ); + mask &= ~(R_TX_EMPTY); + mask |= R_STOP_DETECTED; + REG_WRITE(I2C_INTR_MASK, mask); + } +} + + +void i2c_mst_err_ISR_proc(i2c_info_pt dev) +{ + uint32_t status = REG_READ( I2C_INTR_STAT ); + + if (_Rarely(!status)) + { + return; + } + dev->status_code = 0; + if (status & R_STOP_DETECTED) { + REG_WRITE(I2C_CLR_INTR, R_STOP_DETECTED ); + //REG_WRITE(I2C_INTR_MASK, REG_READ(I2C_INTR_MASK) & ~R_STOP_DETECTED); + end_data_transfer(dev); + } + if( status & R_TX_ABRT ) + { + dev->status_code = status; + REG_WRITE( I2C_CLR_INTR, R_TX_ABRT ); + REG_WRITE( I2C_INTR_MASK, I2C_INT_DSB ); + dev->state = I2C_STATE_READY; + if (_Usually(NULL != dev->err_cb)) + { + dev->err_cb(dev->cb_err_data); + } + } + if( (status & R_TX_OVER)||(status & R_RX_OVER) ) + { + dev->status_code = status; + REG_WRITE( I2C_CLR_INTR, R_TX_OVER|R_RX_OVER ); + REG_WRITE( I2C_INTR_MASK, I2C_INT_DSB ); + dev->state = I2C_STATE_READY; + if (_Usually(NULL != dev->err_cb)) + { + dev->err_cb(dev->cb_err_data); + } + } +} + + +void i2c_mst_rx_avail_ISR_proc(i2c_info_pt dev ) +{ + +#ifndef NDEBUG + uint32_t status = REG_READ( I2C_INTR_STAT ); + + if (_Rarely(!status)) + { + return; + } + + if (status & R_RX_FULL) + { +#endif + recv_data( dev ); + REG_WRITE( I2C_CLR_INTR, R_RX_FULL ); +#ifndef NDEBUG + } +#endif +} + + +void i2c_mst_tx_req_ISR_proc(i2c_info_pt dev) +{ + +#ifndef NDEBUG + uint32_t status = REG_READ( I2C_INTR_STAT ); + + if (_Rarely(!status)) + { + return; + } + + if (status & R_TX_EMPTY) + { +#endif + xmit_data(dev); + REG_WRITE( I2C_CLR_INTR, R_TX_EMPTY); +#ifndef NDEBUG + } +#endif +} + +/* Stop detected ISR - end up here if a STOP condition is asserted on the SDA and SCK signals */ +void i2c_mst_stop_detected_ISR_proc(i2c_info_pt dev) +{ + uint32_t status = REG_READ( I2C_INTR_STAT ); + + if(status & R_STOP_DETECTED) + { + recv_data( dev ); + end_data_transfer( dev ); + } + REG_WRITE( I2C_CLR_INTR, R_STOP_DETECTED ); +} + diff --git a/system/libarc32_edu/drivers/ss_dw_i2c.h b/system/libarc32_edu/drivers/ss_dw_i2c.h new file mode 100644 index 00000000..95f82f52 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_dw_i2c.h @@ -0,0 +1,31 @@ +/* +* +* CONFIDENTIAL AND PROPRIETARY INFORMATION +* +* Copyright (c) 2013 Synopsys, Inc. All rights reserved. +* This software and documentation contain confidential and +* proprietary information that is the property of +* Synopsys, Inc. The software and documentation are +* furnished under a license agreement and may be used +* or copied only in accordance with the terms of the license +* agreement. No part of the software and documentation +* may be reproduced, transmitted, or translated, in any +* form or by any means, electronic, mechanical, manual, +* optical, or otherwise, without prior written permission +* of Synopsys, Inc., or as expressly provided by the license agreement. +* Reverse engineering is prohibited, and reproduction, +* disclosure or use without specific written authorization +* of Synopsys Inc. is strictly forbidden. +*/ + + +#ifndef SS_DW_I2C_H_ +#define SS_DW_I2C_H_ + +void i2c_mst_err_ISR_proc(i2c_info_pt dev); +void i2c_fill_fifo(i2c_info_pt dev); +void i2c_mst_rx_avail_ISR_proc(i2c_info_pt dev); +void i2c_mst_tx_req_ISR_proc(i2c_info_pt dev); +void i2c_mst_stop_detected_ISR_proc(i2c_info_pt dev); + +#endif // SS_DW_I2C_H diff --git a/system/libarc32_edu/drivers/ss_gpio_iface.c b/system/libarc32_edu/drivers/ss_gpio_iface.c new file mode 100644 index 00000000..3de33492 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_gpio_iface.c @@ -0,0 +1,377 @@ +/** INTEL CONFIDENTIAL Copyright 2014-2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#include +#include + +#include "data_type.h" +#include "ss_gpio_iface.h" +#include "soc_register.h" +#include "io_config.h" +#include "eiaextensions.h" +#include "portable.h" + +/* EIA GPIO device registers */ +#define SWPORTA_DR (0x00) /* GPIO Port A Data Register*/ +#define SWPORTA_DDR (0x01) /* GPIO Port A Data Direction Register */ +#define INTEN (0x03) /* GPIO Interrupt Enable Register */ +#define INTMASK (0x04) /* GPIO Interrupt Mask Register */ +#define INTTYPE_LEVEL (0x05) /* GPIO Interrupt Type Register */ +#define INT_POLARITY (0x06) /* GPIO Interrupt Polarity Register */ +#define INTSTATUS (0x07) /* GPIO Interrupt Status Register */ +#define DEBOUNCE (0x08) /* GPIO Debounce Enable Register */ +#define PORTA_EOI (0x09) /* GPIO Port A Clear Interrupt Register */ +#define EXT_PORTA (0x0a) /* GPIO External Port A Register */ +#define LS_SYNC (0x0b) /* GPIO Level-Sensitive Sync Enable and Clock Enable Register */ + +#define GPIO_CLKENA_POS (31) +#define GPIO_CLKENA_MSK (0x1 << GPIO_CLKENA_POS) +#define GPIO_LS_SYNC_POS (0) +#define GPIO_LS_SYNC_MSK (0x1 << GPIO_LS_SYNC_POS) + +#define REG_WRITE( reg, x ) _sr( (unsigned)(x), (unsigned)(dev->reg_base + reg) ) +#define REG_READ( reg ) _lr( (unsigned)(dev->reg_base + reg) ) +#define REG_WRITE_BITS( reg, x, y, len, pos ) REG_WRITE( reg, ( (((x) & ~( (~(0xffffffff << len)) << pos )) \ + | (((y) << pos) & ( (~(0xffffffff << len)) << pos ))) )) +#ifdef __cplusplus + extern "C" { +#endif + +static void ss_gpio_ISR_proc( uint32_t dev_id ); + +/*! \brief Interrupt handler for GPIO port 0 + */ +DECLARE_INTERRUPT_HANDLER static void ss_gpio_8b0_ISR() +{ + ss_gpio_ISR_proc(SS_GPIO_8B0); +} + +/*! \brief Interrupt handler for GPIO port 1 + */ +DECLARE_INTERRUPT_HANDLER static void ss_gpio_8b1_ISR() +{ + ss_gpio_ISR_proc(SS_GPIO_8B1); +} + +typedef void (*ISR) (); + +/*! GPIO management structure */ +typedef struct gpio_info_struct +{ + /* static settings */ + uint32_t reg_base; /*!< base address of device register set */ + uint8_t no_bits; /*!< no of gpio bits in this entity */ + uint8_t vector; /*!< GPIO ISR vector */ + ISR gpio_isr; /*!< GPIO ISR */ + uint32_t gpio_int_mask; /*!< SSS Interrupt Routing Mask Registers */ + gpio_callback_fn *gpio_cb; /*!< Array of user callback functions for user */ + void **gpio_cb_arg; /*!< Array of user priv data for callbacks */ + uint8_t is_init; /*!< Init state of GPIO port */ +} gpio_info_t, *gpio_info_pt; + +static gpio_callback_fn ss_gpio0_cb[SS_GPIO_8B0_BITS] = {NULL}; +static gpio_callback_fn ss_gpio1_cb[SS_GPIO_8B1_BITS] = {NULL}; + +static void* ss_gpio0_arg[SS_GPIO_8B0_BITS] = {NULL}; +static void* ss_gpio1_arg[SS_GPIO_8B1_BITS] = {NULL}; + +static gpio_info_t gpio_ports_devs[] = { + { .is_init = 0, + .reg_base = AR_IO_GPIO_8B0_SWPORTA_DR, + .no_bits = SS_GPIO_8B0_BITS, + .gpio_int_mask = INT_SS_GPIO_0_INTR_MASK, + .vector = IO_GPIO_8B0_INT_INTR_FLAG, + .gpio_cb = ss_gpio0_cb, + .gpio_cb_arg = ss_gpio0_arg, + .gpio_isr = ss_gpio_8b0_ISR }, + { .is_init = 0, + .reg_base = AR_IO_GPIO_8B1_SWPORTA_DR, + .no_bits = SS_GPIO_8B1_BITS, + .gpio_int_mask = INT_SS_GPIO_1_INTR_MASK, + .vector = IO_GPIO_8B1_INT_INTR_FLAG, + .gpio_cb = ss_gpio1_cb, + .gpio_cb_arg = ss_gpio1_arg, + .gpio_isr = ss_gpio_8b1_ISR } + }; + +/* configuration for each GPIO */ +static uint16_t gpio_cfg[SS_GPIO_8B0_BITS+SS_GPIO_8B1_BITS] = { 0 }; + +void* ss_gpio_get_callback_arg(SS_GPIO_PORT port_id, uint8_t pin) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return NULL; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + if (pin >= dev->no_bits) { + return NULL; + } + + return dev->gpio_cb_arg[pin]; +} + +DRIVER_API_RC ss_gpio_set_config(SS_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config) +{ + uint8_t gpio_index = 0, i = 0; + DRIVER_API_RC ret; + uint32_t saved; + + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + + // Check if device is initialized + if(dev->is_init == 0) { + if((ret = ss_gpio_enable(port_id)) != DRV_RC_OK) { + return ret; + } + } + + // Check if pin is already in use + if((config->gpio_type == GPIO_INTERRUPT) && (dev->gpio_cb[bit] != NULL)) { + // pin is already in use + return DRV_RC_CONTROLLER_IN_USE; + } + + // Validate config data + if ((config->gpio_type != GPIO_INPUT) && (config->gpio_type != GPIO_OUTPUT) && (config->gpio_type != GPIO_INTERRUPT)) { + return DRV_RC_INVALID_CONFIG; + } + if ((config->int_type != LEVEL) && (config->int_type != EDGE)) { + return DRV_RC_INVALID_CONFIG; + } + + /* calculate gpio_index */ + for(i = 0; i < port_id; i++){ + gpio_index += gpio_ports_devs[i].no_bits; + } + gpio_index += bit; + gpio_cfg[gpio_index] = 0; + + /* store individual gpio config */ + gpio_cfg[gpio_index] |= (port_id << 9) | (bit << 4) | \ + (config->int_type << 2) | (config->int_polarity << 1) | (config->int_debounce); + + + /* Disable Interrupts from this bit */ + CLEAR_ARC_BIT((volatile uint32_t *)(dev->reg_base+INTEN), bit); + + // Configure interrupt handler + dev->gpio_cb[bit] = config->gpio_cb; + dev->gpio_cb_arg[bit] = config->gpio_cb_arg; + + switch(config->gpio_type) + { + case GPIO_INPUT: + /* configure as input */ + CLEAR_ARC_BIT((volatile uint32_t *)(dev->reg_base+SWPORTA_DDR), bit); + break; + case GPIO_OUTPUT: + /* configure as input */ + SET_ARC_BIT((volatile uint32_t *)(dev->reg_base+SWPORTA_DDR), bit); + break; + case GPIO_INTERRUPT: + saved = interrupt_lock(); + /* Set as input */ + WRITE_ARC_REG(READ_ARC_REG((volatile uint32_t)(dev->reg_base+SWPORTA_DDR)) & ~(1 << bit), + (volatile uint32_t)(dev->reg_base+SWPORTA_DDR)); + + /* Set Level or Edge */ + if(config->int_type == LEVEL) { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INTTYPE_LEVEL))) & ~(1 << bit), + (volatile uint32_t)(dev->reg_base+INTTYPE_LEVEL)); + } else { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INTTYPE_LEVEL))) | (1 << bit), + (volatile uint32_t)(dev->reg_base+INTTYPE_LEVEL)); + } + + /* Set Polarity - Active Low / High */ + if(ACTIVE_LOW == config->int_polarity) { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INT_POLARITY))) & ~(1 << bit), + (volatile uint32_t)(dev->reg_base+INT_POLARITY)); + } else { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INT_POLARITY))) | (1 << bit), + (volatile uint32_t)(dev->reg_base+INT_POLARITY)); + } + + /* Set Debounce - On / Off */ + if(config->int_debounce == DEBOUNCE_OFF) { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+DEBOUNCE))) & ~(1 << bit), + (volatile uint32_t)(dev->reg_base+DEBOUNCE)); + } else { + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+DEBOUNCE))) | (1 << bit), + (volatile uint32_t)(dev->reg_base+DEBOUNCE)); + } + + /* Enable as Interrupt */ + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INTEN))) | (1 << bit), + (volatile uint32_t)(dev->reg_base+INTEN)); + + /* Unmask Interrupt */ + WRITE_ARC_REG((READ_ARC_REG((volatile uint32_t)(dev->reg_base+INTMASK))) & ~(1 << bit), + (volatile uint32_t)(dev->reg_base+INTMASK)); + + interrupt_unlock(saved); + + break; + } + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_enable(SS_GPIO_PORT port_id) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + /* enable peripheral clock */ + SET_ARC_BIT((volatile uint32_t *)(dev->reg_base+LS_SYNC), GPIO_CLKENA_POS); + SET_ARC_BIT((volatile uint32_t *)(dev->reg_base+LS_SYNC), GPIO_LS_SYNC_POS); + /* Clear any existing interrupts */ + REG_WRITE( PORTA_EOI, ~(0)); + /* enable interrupt for this GPIO block */ + SET_INTERRUPT_HANDLER( dev->vector, dev->gpio_isr); + /* Enable GPIO Interrupt into SSS */ + SOC_UNMASK_INTERRUPTS(dev->gpio_int_mask); + + dev->is_init = 1; + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_disable(SS_GPIO_PORT port_id) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + /* Disable All Interrupts from port */ + REG_WRITE(INTEN, 0); + /* disable peripheral clock */ + CLEAR_ARC_BIT((volatile uint32_t *)(dev->reg_base+LS_SYNC), GPIO_CLKENA_POS); + /* Disable GPIO Interrupt into SSS */ + MMIO_REG_VAL(dev->gpio_int_mask) |= DISABLE_SSS_INTERRUPTS; + + dev->is_init = 0; + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_write(SS_GPIO_PORT port_id, uint8_t bit, boolean_t value) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + /* read/modify/write bit */ + if (value) { + SET_ARC_BIT((volatile uint32_t *)(dev->reg_base+SWPORTA_DR), bit); + } else { + CLEAR_ARC_BIT((volatile uint32_t *)(dev->reg_base+SWPORTA_DR), bit); + } + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_write_port(SS_GPIO_PORT port_id, uint32_t value) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + REG_WRITE( SWPORTA_DR, value ); + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_read(SS_GPIO_PORT port_id, uint8_t bit, boolean_t *value) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + // Check pin index + if (bit >= dev->no_bits) { + return DRV_RC_CONTROLLER_NOT_ACCESSIBLE; + } + if (REG_READ(SWPORTA_DDR) & (1 << bit)) { + return DRV_RC_INVALID_OPERATION; /* not configured as input */ + } + *value = !!(REG_READ(EXT_PORTA) & (1 << bit)); + return DRV_RC_OK; +} + +DRIVER_API_RC ss_gpio_read_port(SS_GPIO_PORT port_id, uint32_t *value) +{ + // check port id + if(port_id >= SS_PORT_COUNT) { + return DRV_RC_INVALID_OPERATION; + } + gpio_info_pt dev = &gpio_ports_devs[port_id]; + + *value = REG_READ(EXT_PORTA); + return DRV_RC_OK; +} + +static void ss_gpio_ISR_proc( uint32_t dev_id ) +{ + unsigned int i; + gpio_info_pt dev = &gpio_ports_devs[dev_id]; + + // Save interrupt status + uint32_t status = REG_READ( INTSTATUS ); + // Clear interrupt flag (write 1 to clear) + REG_WRITE( PORTA_EOI, status ); + + for (i=0; ino_bits; i++) { + if ((status & (1 << i)) && (dev->gpio_cb[i])) { + (dev->gpio_cb[i])(status, dev->gpio_cb_arg[i]); + } + } +} + +#ifdef __cplusplus +} +#endif diff --git a/system/libarc32_edu/drivers/ss_gpio_iface.h b/system/libarc32_edu/drivers/ss_gpio_iface.h new file mode 100644 index 00000000..02d2bc74 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_gpio_iface.h @@ -0,0 +1,177 @@ +/** INTEL CONFIDENTIAL Copyright 2014-2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef SS_GPIO_IFACE_H_ +#define SS_GPIO_IFACE_H_ + +/** + * \addtogroup arc_driver + * @{ + * \defgroup gpio_arc_driver GPIO: General Purpose Input/Output API + * @{ + * \brief Definition of the structure and functions used by GPIO ARC Driver implementation. + */ + +#include "data_type.h" +#include "gpio.h" + +#define SS_GPIO_8B0_BITS (8) +#define SS_GPIO_8B1_BITS (8) + +/*! + * Port list + */ +typedef enum { + SS_GPIO_8B0=0, /*!< GPIO port for pins from 0 to 7 */ + SS_GPIO_8B1, /*!< GPIO port for pins from 8 to 15 */ + SS_PORT_COUNT /*!< GPIO port count */ +} SS_GPIO_PORT; + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn DRIVER_API_RC ss_gpio_set_config(SS_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config) +* +* \brief Function to configure specified GPIO bit in specified GPIO port +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param config : pointer to configuration structure +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_set_config(SS_GPIO_PORT port_id, uint8_t bit, gpio_cfg_data_t *config); + +/*! \fn void* ss_gpio_get_callback_arg(SS_GPIO_PORT port_id, uint8_t pin) +* +* \brief Function to get callback argument pointer for a specific pin +* +* \param port_id : GPIO port identifier +* \param bit : pin in port to configure +* \param config : configuration data to apply +* +* \return ptr if success else NULL +*/ +void* ss_gpio_get_callback_arg(SS_GPIO_PORT port_id, uint8_t pin); + +/*! \fn DRIVER_API_RC ss_gpio_enable(SS_GPIO_PORT port_id) +* +* \brief Function to enable the specified GPIO port +* Upon success, the specified GPIO port is no longer clock gated in hardware, it is now +* capable of reading and writing GPIO bits and of generating interrupts. +* +* \param port_id : GPIO port identifier +* \param pin : bit in port to configure +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_enable(SS_GPIO_PORT port_id); + +/*! \fn DRIVER_API_RC ss_gpio_disable(SS_GPIO_PORT port_id) +* +* \brief Function to disable the specified GPIO port +* Upon success, the specified GPIO port is clock gated in hardware, it is now +* incapable of reading, writing GPIO bits and of generating interrupts. +* +* \param port_id : GPIO port identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if port id is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if port/bit is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if port/bit is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_disable(SS_GPIO_PORT port_id); + +/*! \fn DRIVER_API_RC ss_gpio_write(SS_GPIO_PORT port_id, uint8_t bit, boolean_t value) +* +* \brief Function to transmit a block of data to the specified SPI slave +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param value : value to write to bit +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_write(SS_GPIO_PORT port_id, uint8_t bit, boolean_t value); + + +/*! \fn DRIVER_API_RC ss_gpio_read(SS_GPIO_PORT port_id, uint8_t bit, boolean_t *value) +* +* \brief Function to read a GPIO bit +* +* \param port_id : GPIO port identifier +* \param bit : bit in port to configure +* \param *value : address to place read value +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_read(SS_GPIO_PORT port_id, uint8_t bit, boolean_t *value); + +/*! \fn DRIVER_API_RC ss_gpio_write_port(SS_GPIO_PORT port_id, uint32_t value) +* +* \brief Function to write to a value to a given port +* +* \param port_id : GPIO port identifier +* \param value : value to write to port +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_write_port(SS_GPIO_PORT port_id, uint32_t value); + +/*! \fn DRIVER_API_RC ss_gpio_read_port(SS_GPIO_PORT port_id, uint32_t *value) +* +* \brief Function to read a given port +* +* \param port_id : GPIO port identifier +* \param *value : location to store result +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_gpio_read_port(SS_GPIO_PORT port_id, uint32_t *value); + +#ifdef __cplusplus +} +#endif + +#endif /* SS_GPIO_IFACE_H_ */ + +/**@} @}*/ diff --git a/system/libarc32_edu/drivers/ss_i2c_iface.c b/system/libarc32_edu/drivers/ss_i2c_iface.c new file mode 100644 index 00000000..bd15e958 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_i2c_iface.c @@ -0,0 +1,455 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#include +#include + +#include "data_type.h" +#include "ss_i2c_iface.h" +#include "soc_register.h" +#include "io_config.h" +#include "i2c_priv.h" +#include "eiaextensions.h" +#include "ss_dw_i2c.h" +#include "portable.h" + +#define I2C_SS_NUM_CONTROLLERS (2) +#define IO_I2C_MST0_PRESENT +#define IO_I2C_MST1_PRESENT + +#define SS_CTRL_ID(x) (x-I2C_SENSING_0) /* Use this to translate from System controller ID to SSS ID */ +#define I2C_ADDRESS_MASK ~( (~(0xffffffff << 10)) << 9 ) /* Use this to zero I2C address in I2CON */ + +#ifdef __cplusplus + extern "C" { +#endif + +static DRIVER_API_RC is_valid_controller(I2C_CONTROLLER id); +static DRIVER_API_RC is_controller_available(I2C_CONTROLLER id); +static void copy_config_data(i2c_cfg_data_t *cfg, I2C_CONTROLLER controller_id); + +/* I2C master devices private data structures */ +static i2c_info_pt i2c_handles[I2C_SS_NUM_CONTROLLERS] = { 0 }; + + +#ifdef IO_I2C_MST0_PRESENT +DECLARE_INTERRUPT_HANDLER static void i2c_mst0_err_ISR() +{ + i2c_mst_err_ISR_proc( i2c_handles[0] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst0_rx_avail_ISR() +{ + i2c_mst_rx_avail_ISR_proc( i2c_handles[0] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst0_tx_req_ISR() +{ + i2c_mst_tx_req_ISR_proc( i2c_handles[0] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst0_stop_detected_ISR() +{ + i2c_mst_stop_detected_ISR_proc( i2c_handles[0] ); +} +#endif +#ifdef IO_I2C_MST1_PRESENT +DECLARE_INTERRUPT_HANDLER static void i2c_mst1_err_ISR() +{ + i2c_mst_err_ISR_proc( i2c_handles[1] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst1_rx_avail_ISR() +{ + i2c_mst_rx_avail_ISR_proc( i2c_handles[1] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst1_tx_req_ISR() +{ + i2c_mst_tx_req_ISR_proc( i2c_handles[1] ); +} +DECLARE_INTERRUPT_HANDLER static void i2c_mst1_stop_detected_ISR() +{ + i2c_mst_stop_detected_ISR_proc( i2c_handles[1] ); +} +#endif + + + +static i2c_info_t i2c_master_devs[] = { +#ifdef IO_I2C_MST0_PRESENT + { .instID = 0, + .reg_base = AR_IO_I2C_MST0_CON, + .fifo_depth = IO_I2C_MST0_FS, + .vector_err = IO_I2C_MST0_INT_ERR, + .isr_err = i2c_mst0_err_ISR, + .vector_rx_avail = IO_I2C_MST0_INT_RX_AVAIL, + .isr_rx_avail = i2c_mst0_rx_avail_ISR, + .vector_tx_req = IO_I2C_MST0_INT_TX_REQ, + .isr_tx_req = i2c_mst0_tx_req_ISR, + .vector_stop_detected = IO_I2C_MST0_INT_STOP_DETECTED, + .isr_stop_detected = i2c_mst0_stop_detected_ISR, + .i2c_rx_avail_mask = SCSS_REGISTER_BASE + INT_SS_I2C_0_RX_AVAIL_MASK, + .i2c_tx_req_mask = SCSS_REGISTER_BASE + INT_SS_I2C_0_TX_REQ_MASK, + .i2c_stop_detected_mask = SCSS_REGISTER_BASE + INT_SS_I2C_0_STOP_DETECTED_MASK, + .i2c_err_mask = SCSS_REGISTER_BASE + INT_SS_I2C_0_ERR_MASK, + .creg_i2c_clk_ctrl = CREG_CLK_CTRL_I2C0 }, +#endif +#ifdef IO_I2C_MST1_PRESENT + { .instID = 1, + .reg_base = AR_IO_I2C_MST1_CON, + .fifo_depth = IO_I2C_MST1_FS, + .vector_err = IO_I2C_MST1_INT_ERR, + .isr_err = i2c_mst1_err_ISR, + .vector_rx_avail = IO_I2C_MST1_INT_RX_AVAIL, + .isr_rx_avail = i2c_mst1_rx_avail_ISR, + .vector_tx_req = IO_I2C_MST1_INT_TX_REQ, + .isr_tx_req = i2c_mst1_tx_req_ISR, + .vector_stop_detected = IO_I2C_MST1_INT_STOP_DETECTED, + .isr_stop_detected = i2c_mst1_stop_detected_ISR, + .i2c_rx_avail_mask = SCSS_REGISTER_BASE + INT_SS_I2C_1_RX_AVAIL_MASK, + .i2c_tx_req_mask = SCSS_REGISTER_BASE + INT_SS_I2C_1_TX_REQ_MASK, + .i2c_stop_detected_mask = SCSS_REGISTER_BASE + INT_SS_I2C_1_STOP_DETECTED_MASK, + .i2c_err_mask = SCSS_REGISTER_BASE + INT_SS_I2C_1_ERR_MASK, + .creg_i2c_clk_ctrl = CREG_CLK_CTRL_I2C1 }, +#endif + { .instID = I2C_SS_NUM_CONTROLLERS } + }; + + +typedef struct ss_i2c_cfg_driver_data +{ + i2c_cfg_data_t public; + + struct ss_i2c_cfg_priv_data{ + uint32_t hold_time, + setup_time, + spk_len, + ss_hcnt, + ss_lcnt, + fs_hcnt, + fs_lcnt, + rx_thresh, + tx_thresh; + }priv; +}ss_i2c_cfg_driver_data_t; + +static ss_i2c_cfg_driver_data_t drv_config[2]; + +DRIVER_API_RC ss_i2c_set_config(I2C_CONTROLLER controller_id, i2c_cfg_data_t *config) +{ + DRIVER_API_RC rc = DRV_RC_OK; + i2c_info_pt dev = 0;; + uint32_t i2c_con = 0; + ss_i2c_cfg_driver_data_t *drv_cfg = 0;; + + copy_config_data(config, controller_id); + drv_cfg = &drv_config[SS_CTRL_ID(controller_id)]; + + /* check controller_id is valid and not in use */ + if((rc=is_valid_controller(controller_id)) != DRV_RC_OK) + { + return rc; + } + if((rc=is_controller_available(controller_id)) != DRV_RC_OK) + { + return rc; + } + + /* do some check here to see if this controller is accessible form this core */ + + dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + i2c_handles[SS_CTRL_ID(controller_id)] = dev; + + /* enable clock to controller to allow reg writes */ + REG_WRITE( I2C_CON, I2C_CLK_ENABLED ); + /* disable interrupts while doing config */ + REG_WRITE( I2C_INTR_MASK, I2C_INT_DSB ); + + i2c_con = ( I2C_CLK_ENABLED | (drv_cfg->priv.spk_len << 22) | (drv_cfg->public.slave_adr << 9) | (drv_cfg->public.speed << 3)); + i2c_con |= drv_cfg->public.addressing_mode << 5; // 7 or 10 bit + + i2c_con |= I2C_RESTART_EN; + + REG_WRITE( I2C_CON, i2c_con ); + + REG_WRITE( I2C_TL, ( drv_cfg->priv.tx_thresh << 16 ) | drv_cfg->priv.rx_thresh); + REG_WRITE( I2C_SDA_CONFIG, ( drv_cfg->priv.setup_time << 16 ) | drv_cfg->priv.hold_time ); + REG_WRITE( I2C_SS_SCL_CNT, ( drv_cfg->priv.ss_hcnt << 16 ) | drv_cfg->priv.ss_lcnt ); + REG_WRITE( I2C_FS_SCL_CNT, ( drv_cfg->priv.fs_hcnt << 16 ) | drv_cfg->priv.fs_lcnt ); + + + /* user callbacks */ + dev->err_cb = drv_cfg->public.cb_err; + dev->tx_cb = drv_cfg->public.cb_tx; + dev->rx_cb = drv_cfg->public.cb_rx; + dev->cb_err_data = drv_cfg->public.cb_err_data; + dev->cb_tx_data = drv_cfg->public.cb_tx_data; + dev->cb_rx_data = drv_cfg->public.cb_rx_data; + + dev->state = I2C_STATE_READY; + + + /* disable device */ + i2c_con &= ~(I2C_ENABLE_MASTER); // 0 disables master + REG_WRITE( I2C_CON, i2c_con ); + + /* set interrupt vector, mid/high priority */ + SET_INTERRUPT_HANDLER( dev->vector_err, dev->isr_err); + SET_INTERRUPT_HANDLER( dev->vector_rx_avail, dev->isr_rx_avail); + SET_INTERRUPT_HANDLER( dev->vector_tx_req, dev->isr_tx_req); + SET_INTERRUPT_HANDLER( dev->vector_stop_detected, dev->isr_stop_detected); + + /* + * SoC I2C config + */ + /* Setup I2C Interrupt Routing Mask Registers to allow interrupts through */ + MMIO_REG_VAL(dev->i2c_rx_avail_mask) &= ENABLE_SSS_INTERRUPTS; + MMIO_REG_VAL(dev->i2c_tx_req_mask) &= ENABLE_SSS_INTERRUPTS; + MMIO_REG_VAL(dev->i2c_stop_detected_mask) &= ENABLE_SSS_INTERRUPTS; + MMIO_REG_VAL(dev->i2c_err_mask) &= ENABLE_SSS_INTERRUPTS; + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_i2c_deconfig(I2C_CONTROLLER controller_id) +{ + i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + uint32_t creg = 0; + + dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + /* Set I2C registers to hardware reset state */ + REG_WRITE( I2C_DATA_CMD,0); + REG_WRITE( I2C_SS_SCL_CNT,0); + REG_WRITE( I2C_FS_SCL_CNT,0); + REG_WRITE( I2C_INTR_STAT,0); + REG_WRITE( I2C_INTR_MASK,0); + REG_WRITE( I2C_TL,0); + REG_WRITE( I2C_CLR_INTR,0); + REG_WRITE( I2C_STATUS,0); + REG_WRITE( I2C_TXFLR,0); + REG_WRITE( I2C_RXFLR,0); + REG_WRITE( I2C_SDA_CONFIG,0); + REG_WRITE( I2C_TX_ABRT_SOURCE,0); + REG_WRITE( I2C_ENABLE_STATUS,0); + + creg = _lr(AR_IO_CREG_MST0_CTRL); // CREG Master + creg &= ~( 1 << dev->creg_i2c_clk_ctrl); + + /* disable interrupts while doing config */ + REG_WRITE( I2C_INTR_MASK, I2C_INT_DSB ); + /* disable controller */ + REG_WRITE( I2C_CON, 0); + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_i2c_clock_enable(I2C_CONTROLLER controller_id) +{ + i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + uint32_t saved; + + /* Protect registers using lock and unlockl of interruptions */ + saved = interrupt_lock(); + + /* enable clock to peripheral */ + WRITE_ARC_REG(READ_ARC_REG((volatile uint32_t)(AR_IO_CREG_MST0_CTRL)) | ( 1 << dev->creg_i2c_clk_ctrl), + (volatile uint32_t)(AR_IO_CREG_MST0_CTRL)); + + /* enable device */ + WRITE_ARC_REG(READ_ARC_REG((volatile uint32_t)(dev->reg_base+I2C_CON)) | I2C_ENABLE_MASTER, + (volatile uint32_t)(dev->reg_base+I2C_CON)); + + interrupt_unlock(saved); + + return DRV_RC_OK; +} + +DRIVER_API_RC ss_i2c_clock_disable(I2C_CONTROLLER controller_id) +{ + i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + uint32_t saved; + + ///* wait for tx empty and bus idle */ + //while((REG_READ(I2C_STATUS) & I2C_STATUS_MASTER_ACT) || !(REG_READ(I2C_STATUS) & I2C_STATUS_TFE)); + + /* Protect registers using lock and unlockl of interruptions */ + saved = interrupt_lock(); + + /* disable clock to peripheral */ + WRITE_ARC_REG(READ_ARC_REG((volatile uint32_t)(AR_IO_CREG_MST0_CTRL)) & ~( 1 << dev->creg_i2c_clk_ctrl), + (volatile uint32_t)(AR_IO_CREG_MST0_CTRL)); + + /* disable device */ + WRITE_ARC_REG(READ_ARC_REG((volatile uint32_t)(dev->reg_base+I2C_CON)) & ~(I2C_ENABLE_MASTER), + (volatile uint32_t)(dev->reg_base+I2C_CON)); + + interrupt_unlock(saved); + + return DRV_RC_OK; + +} + +DRIVER_API_RC ss_i2c_write(I2C_CONTROLLER controller_id, uint8_t *data_write, uint32_t data_write_len, uint32_t slave_addr) +{ + return ss_i2c_transfer(controller_id, data_write, data_write_len, 0 , 0, slave_addr); +} + +DRIVER_API_RC ss_i2c_read(I2C_CONTROLLER controller_id, uint8_t *data_read, uint32_t data_read_len, uint32_t slave_addr) +{ + return ss_i2c_transfer(controller_id, 0, 0, data_read, data_read_len, slave_addr); +} + +DRIVER_API_RC ss_i2c_transfer(I2C_CONTROLLER controller_id, uint8_t *data_write, uint32_t data_write_len, uint8_t *data_read, uint32_t data_read_len, uint32_t slave_addr){ + i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + uint32_t i2c_con = 0; + uint32_t saved; + + if ((REG_READ(I2C_STATUS) & I2C_STATUS_MASTER_ACT) || !(REG_READ(I2C_STATUS) & I2C_STATUS_TFE)) + { + return DRV_RC_FAIL; + } + /* Protect registers using lock and unlockl of interruptions */ + saved = interrupt_lock(); + + i2c_con = READ_ARC_REG((volatile uint32_t)(dev->reg_base+I2C_CON)); + i2c_con &= I2C_ADDRESS_MASK; // zero slave addr first + i2c_con |= (slave_addr << 9); + WRITE_ARC_REG(i2c_con, (volatile uint32_t)(dev->reg_base+I2C_CON)); + + interrupt_unlock(saved); + + if (data_read_len > 0) + { + dev->state = I2C_STATE_RECEIVE; + } + else + { + dev->state = I2C_STATE_TRANSMIT; + } + dev->rx_len = data_read_len; + dev->tx_len = data_write_len; + dev->rx_tx_len = data_read_len + data_write_len; + dev->i2c_write_buff = data_write; + dev->i2c_read_buff = data_read; + dev->total_read_bytes = 0; + dev->total_write_bytes = 0; + + if (REG_READ(I2C_STATUS) & I2C_STATUS_TFE ) { + int flags = interrupt_lock(); + i2c_fill_fifo(dev); + interrupt_unlock(flags); + } + + REG_WRITE( I2C_INTR_MASK, I2C_INT_ENB | R_TX_EMPTY ); + + return DRV_RC_OK; +} + +DRIVER_I2C_STATUS_CODE ss_i2c_status(I2C_CONTROLLER controller_id) +{ + i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + DRIVER_I2C_STATUS_CODE rc = I2C_OK; + uint32_t int_status = 0; + uint32_t status = 0; + + status = REG_READ(I2C_STATUS); + if ((status & I2C_STATUS_MASTER_ACT) || (status & I2C_STATUS_RFNE) || !(status & I2C_STATUS_TFE)) + { + rc = I2C_BUSY; + } + else + { + int_status = REG_READ(I2C_INTR_STAT); + if(int_status & R_TX_ABRT) + { + rc = I2C_TX_ABORT; + } + if(int_status & R_TX_OVER) + { + rc = I2C_TX_OVER; + } + if(int_status & R_RX_OVER) + { + rc = I2C_RX_OVER; + } + if(int_status & R_RX_UNDER) + { + rc = I2C_RX_UNDER; + } + } + + return rc; +} + +/* + * Check to see if this controller is part of the design ( determined at build time ) + */ +static DRIVER_API_RC is_valid_controller(I2C_CONTROLLER controller_id) +{ + + // do checks here + return DRV_RC_OK; +} +/* + * Check to see if controller is not in use + */ +static DRIVER_API_RC is_controller_available(I2C_CONTROLLER controller_id) +{ +// i2c_info_pt dev = &i2c_master_devs[SS_CTRL_ID(controller_id)]; + +// if(REG_READ(I2C_CON) & I2C_ENABLE_MASTER) +// return DRV_RC_CONTROLLER_IN_USE; + + // do checks here + return DRV_RC_OK; +} + +static void copy_config_data(i2c_cfg_data_t *cfg, I2C_CONTROLLER controller_id) +{ + uint32_t id = SS_CTRL_ID(controller_id); + + /* copy passed in config data locally */ + drv_config[id].public.speed = cfg->speed; + drv_config[id].public.addressing_mode = cfg->addressing_mode; + drv_config[id].public.mode_type = cfg->mode_type; + drv_config[id].public.slave_adr = cfg->slave_adr; + drv_config[id].public.cb_rx = cfg->cb_rx; + drv_config[id].public.cb_rx_data = cfg->cb_rx_data; + drv_config[id].public.cb_tx = cfg->cb_tx; + drv_config[id].public.cb_tx_data = cfg->cb_tx_data; + drv_config[id].public.cb_err = cfg->cb_err; + drv_config[id].public.cb_err_data = cfg->cb_err_data; + + /* TODO default private data - may need to look at this.*/ + drv_config[id].priv.hold_time = I2C_HOLD_TIME; + drv_config[id].priv.setup_time = I2C_SETUP_TIME; + drv_config[id].priv.spk_len = I2C_SPKLEN; + drv_config[id].priv.ss_hcnt = I2C_SS_SCL_HIGH_COUNT; + drv_config[id].priv.ss_lcnt = I2C_SS_SCL_LOW_COUNT; + drv_config[id].priv.fs_hcnt = I2C_FS_SCL_HIGH_COUNT; + drv_config[id].priv.fs_lcnt = I2C_FS_SCL_LOW_COUNT; + drv_config[id].priv.rx_thresh = I2C_RX_FIFO_THRESHOLD; + drv_config[id].priv.tx_thresh = I2C_TX_FIFO_THRESHOLD; + +} + +#ifdef __cplusplus +} +#endif diff --git a/system/libarc32_edu/drivers/ss_i2c_iface.h b/system/libarc32_edu/drivers/ss_i2c_iface.h new file mode 100644 index 00000000..5e491e93 --- /dev/null +++ b/system/libarc32_edu/drivers/ss_i2c_iface.h @@ -0,0 +1,195 @@ +/** INTEL CONFIDENTIAL Copyright 2015 Intel Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. + * Title to the Material remains with Intel Corporation or its suppliers and + * licensors. + * The Material contains trade secrets and proprietary and confidential information + * of Intel or its suppliers and licensors. The Material is protected by worldwide + * copyright and trade secret laws and treaty provisions. + * No part of the Material may be used, copied, reproduced, modified, published, + * uploaded, posted, transmitted, distributed, or disclosed in any way without + * Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. + * + * Any license under such intellectual property rights must be express and + * approved by Intel in writing + * + ******************************************************************************/ + +#ifndef SS_I2C_IFACE_H_ +#define SS_I2C_IFACE_H_ + +/** + * \addtogroup arc_driver + * @{ + * \defgroup i2c_arc_driver I2C: Inter-Integrated Circuit API + * @{ + * \brief Definition of the structure and functions used by I2C ARC Driver implementation. + */ + +#include "data_type.h" +#include "common_i2c.h" + +/*! + * List of all controllers in system ( IA and SS ) + */ + +typedef enum { + I2C_SENSING_0 = 0, /*!< Sensing I2C controller 0, accessibly by Sensor Subsystem Core only */ + I2C_SENSING_1 /*!< Sensing I2C controller 1, accessible by Sensor Subsystem Core only */ +} I2C_CONTROLLER; + +#ifdef __cplusplus + extern "C" { +#endif + +/*! \fn DRIVER_API_RC ss_i2c_set_config(I2C_CONTROLLER controller_id, i2c_cfg_data_t *config) +* +* \brief Function to configure specified I2C controller +* Configuration parameters must be valid or an error is returned - see return values below. +* +* \param controller_id : I2C controller_id identifier +* \param config : pointer to configuration structure +* +* \return DRV_RC_OK on success\n +* DRV_RC_DEVICE_TYPE_NOT_SUPPORTED - if device type is not supported by this controller\n +* DRV_RC_INVALID_CONFIG - if any configuration parameters are not valid\n +* DRV_RC_CONTROLLER_IN_USE, if controller is in use\n +* DRV_RC_CONTROLLER_NOT_ACCESSIBLE if controller is not accessible from this core\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_set_config(I2C_CONTROLLER controller_id, i2c_cfg_data_t *config); + + +/*! \fn DRIVER_API_RC ss_i2c_get_config(I2C_CONTROLLER controller_id, i2c_cfg_data_t *config) +* +* \brief Function to retrieve configuration of specified I2C controller +* +* \param controller_id : I2C controller_id identifier +* \param config : pointer to configuration structure to store current setup +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_get_config(I2C_CONTROLLER controller_id, i2c_cfg_data_t *config); + + +/*! \fn DRIVER_API_RC ss_i2c_deconfig(I2C_CONTROLLER controller_id) +* +* \brief Function to place I2C controller into a disabled and default state (as if hardware reset occurred) +* This function assumes that there is no pending transaction on the I2C interface in question. +* It is the responsibility of the calling application to do so. +* Upon success, the specified I2C interface is clock gated in hardware, +* it is no longer capable to generating interrupts, it is also configured into a default state +* +* \param controller_id : I2C controller_id identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_deconfig(I2C_CONTROLLER controller_id); + + +/*! \fn DRIVER_API_RC ss_i2c_clock_enable(I2C_CONTROLLER controller_id) +* +* \brief Function to enable the specified I2C controller +* Upon success, the specified I2C interface is no longer clock gated in hardware, it is now +* capable of transmitting and receiving on the I2C bus and of generating interrupts. +* +* \param controller_id : I2C controller_id identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_clock_enable(I2C_CONTROLLER controller_id); + + +/*! \fn DRIVER_API_RC ss_i2c_clock_disable(I2C_CONTROLLER controller_id) +* +* \brief Function to disable the specified I2C controller. +* This function assumes that there is no pending transaction on the I2C interface in question. +* It is the responsibility of the calling application to do so. +* Upon success, the specified I2C interface is clock gated in hardware, +* it is no longer capable of generating interrupts. +* +* \param controller_id : I2C controller_id identifier +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_clock_disable(I2C_CONTROLLER controller_id); + + +/*! \fn DRIVER_API_RC ss_i2c_write(I2C_CONTROLLER controller_id, uint8_t *data, uint32_t data_len, uint32_t slave_addr) +* +* \brief Function to transmit a block of data to the specified I2C slave +* +* \param controller_id : I2C controller_id identifier +* \param data : pointer to data to write +* \param data_len : length of data to write +* \param slave_addr : I2C address of the slave to write data to +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_write(I2C_CONTROLLER controller_id, uint8_t *data, uint32_t data_len, uint32_t slave_addr); + + +/*! \fn DRIVER_API_RC ss_i2c_read(I2C_CONTROLLER controller_id, uint8_t *data, uint32_t data_len, uint32_t slave_addr) +* +* \brief Function to receive a block of data +* If set as a master, this will receive 'data_len' bytes transmitted from slave +* If set as a slave, this will receive any data sent by a master addressed to the this I2C address as +* configured in the "slave_adr" for this controller configuration, in which case 'data_len' +* indicates the amount of data received and 'data' holds the data +* +* \param controller_id : I2C controller_id identifier +* \param data : pointer to data to read +* \param data_len : length of data to read +* \param slave_addr : I2C address of the slave to read from +* +* \return DRV_RC_OK on success\n +* DRV_RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_read(I2C_CONTROLLER controller_id, uint8_t *data, uint32_t data_len, uint32_t slave_addr); + +/*! \fn DRIVER_API_RC soc_i2c_transfer(I2C_CONTROLLER controller_id, uint8_t *data_write, uint32_t data_write_len, uint8_t *data_read, uint32_t data_read_len, uint32_t slave_addr) +* +* \brief Function to transmit and receive a block of data to the specified I2C slave +* with repeated start +* +* \param controller_id : I2C controller_id identifier +* \param data_write : pointer to data to write +* \param data_write_len : length of data to write +* \param data_read : pointer to data to read +* \param data_read_len : length of data to read +* \param slave_addr : I2C address of the slave to write data to +* +* \return RC_OK on success\n +* RC_FAIL otherwise +*/ +DRIVER_API_RC ss_i2c_transfer(I2C_CONTROLLER controller_id, uint8_t *data_write, uint32_t data_write_len, uint8_t *data_read, uint32_t data_read_len, uint32_t slave_addr); + +/*! \fn DRIVER_I2C_STATUS_CODE ss_i2c_status(I2C_CONTROLLER controller_id) +* +* \brief Function to determine controllers current state +* +* \param controller_id : I2C controller identifier +* +* \return I2C_OK - controller ready, I2C_BUSY - controller busy +*/ +DRIVER_I2C_STATUS_CODE ss_i2c_status(I2C_CONTROLLER controller_id); + +#ifdef __cplusplus +} +#endif + +#endif /* SS_I2C_IFACE_H_ */ + +/**@} @}*/ diff --git a/system/libarc32_edu/main.c b/system/libarc32_edu/main.c new file mode 100644 index 00000000..baffe56e --- /dev/null +++ b/system/libarc32_edu/main.c @@ -0,0 +1,119 @@ +/* +Copyright (c) 2015 Intel Corporation. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +#include + +#include "drivers/soc_gpio.h" +#include "drivers/arcv2_timer1.h" +#include "scss_registers.h" + +#define GPIO_2 2 + +#define PIN13 GPIO_2 + +#define OUTPUT 0 +#define INPUT 1 + +#define LOW 0 +#define HIGH 1 + +static void configure_soc_gpio(pin, mode) +{ + gpio_cfg_data_t cfg; + uint8_t bit; + + memset(&cfg, 0, sizeof(cfg)); + + cfg.gpio_type = (mode == OUTPUT) ? GPIO_OUTPUT : GPIO_INPUT; + + switch(pin) { + case 13: + bit = 2; + break; + default: + // Invalid/not-supported + return; + }; + + soc_gpio_set_config(SOC_GPIO_32, bit, &cfg); +} + +void pinMode(pin, mode) +{ + switch(pin) { + case 13: + configure_soc_gpio(pin, mode); + break; + default: + // Invalid/not-supported + return; + }; +} + +void digitalWrite(pin, state) +{ + uint8_t bit; + + switch(pin) { + case 13: + bit = 2; + break; + default: + // Invalid/not-supported + return; + }; + + soc_gpio_write(SOC_GPIO_32, bit, state); +} + +#define TIMER1_TICK 500 +void timer1_user_isr(void) +{ + uint8_t static pin_state = LOW; + pin_state = !pin_state; + digitalWrite(13, pin_state); +} + +void setup(void) +{ + pinMode(13, OUTPUT); + timer1_driver_init(timer1_user_isr, TIMER1_TICK); +} + +#define DELAY_CYCLES 1000000 +void loop(void) +{ + unsigned i; + for (i = 0; i < DELAY_CYCLES; i++) + digitalWrite(13, HIGH); + for (i = 0; i < DELAY_CYCLES; i++) + digitalWrite(13, LOW); +} + +int main(void) +{ + soc_gpio_enable(SOC_GPIO_32); + SET_PIN_MODE(2, QRK_PMUX_SEL_MODEA); + + setup(); + for(;;) + __asm__("nop"); +// loop(); + + __builtin_unreachable(); +} diff --git a/variants/intel_edu_x/libarc32drv_edu.a b/variants/intel_edu_x/libarc32drv_edu.a new file mode 100755 index 00000000..0f375dca Binary files /dev/null and b/variants/intel_edu_x/libarc32drv_edu.a differ diff --git a/variants/intel_edu_x/linker_scripts/flash.ld b/variants/intel_edu_x/linker_scripts/flash.ld new file mode 100644 index 00000000..aec52454 --- /dev/null +++ b/variants/intel_edu_x/linker_scripts/flash.ld @@ -0,0 +1,145 @@ +/* linker.cmd - Linker command/script file */ + +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * The right to copy, distribute, modify or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ + +/* +modification history +-------------------- +03Nov14,j_b written +16Apr15,dod trimmed down for Atlas-Edge version +*/ + +/* +DESCRIPTION +Linker script for the Atlas Peak ARC BSPs. +*/ + +OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") + +MEMORY + { + FLASH (rx) : ORIGIN = 0x40000000, LENGTH = 192K + SRAM (wx) : ORIGIN = 0xa8010000, LENGTH = 16K + DCCM (wx) : ORIGIN = 0x80000000, LENGTH = 8K + } + +/* Putting stack at end of SRAM for now */ +__stack_start = ORIGIN(SRAM)+LENGTH(SRAM); + +SECTIONS + { +/* FLASH Start */ + + version_header_section : + { + *(.version_header) + KEEP(*(".version_header*")) + } > FLASH + + text : ALIGN(1024) + { + __text_start = .; + +/* when !XIP, .text is in RAM, and vector table must be at its very start */ + KEEP(*(.int_vector_table)) + KEEP(*(".int_vector_table.*")) + + *(.text) + *(".text.*") + __text_end = .; + } > FLASH + + ctors : + { + /* + * The compiler fills the constructor pointers table below, hence symbol + * __ctor_table_start must be aligned on 4 byte boundary. + * To align with the C++ standard, the first element of the array + * contains the number of actual constructors. The last element is + * NULL. + */ + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + KEEP(*(SORT(".ctors*"))) + LONG(0) + __CTOR_END__ = .; + } > FLASH + + rodata : + { + *(.rodata) + *(".rodata.*") + } > FLASH + + __data_rom_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ + +/* FLASH End */ + +/* SRAM Start */ + + datas : AT(__data_rom_start) + { + +/* when XIP, .text is in ROM, but vector table must be at start of .data */ + + __data_ram_start = .; + *(.data) + *(".data.*") + } > SRAM + + __data_ram_end = .; + + bss (NOLOAD) : + { + /* + * For performance, BSS section is assumed to be 4 byte aligned and + * a multiple of 4 bytes + */ + . = ALIGN(4); + __bss_start = .; + *(.bss) + *(".bss.*") + *(COMMON) + /* + * BSP clears this memory in words only and doesn't clear any + * potential left over bytes. + */ + __bss_end = ALIGN(4); + } > SRAM + + noinit (NOLOAD) : + { + /* + * This section is used for non-intialized objects that + * will not be cleared during the boot process. + */ + *(.noinit) + *(".noinit.*") + /* + * The seg_rxtx section is used by the Host IO module for + * allocating RX/TX buffers. If a specific memory location is + * required for these buffers, then a MEMORY definition should be + * made. + */ + *(.seg_rxtx) + *(".seg_rxtx.*") + } > SRAM + + /* Define linker symbols */ + + _end = .; /* end of image */ + +/* SRAM End */ + + /* Data Closely Coupled Memory (DCCM) */ +/* DCCM Start */ +/* DCCM End */ + + } diff --git a/variants/intel_edu_x/pins_arduino.h b/variants/intel_edu_x/pins_arduino.h new file mode 100644 index 00000000..b5c13452 --- /dev/null +++ b/variants/intel_edu_x/pins_arduino.h @@ -0,0 +1,57 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#define NUM_DIGITAL_PINS 20 +#define NUM_ANALOG_INPUTS 6 +#define NUM_PWM 4 +#define NUM_UARTS 1 +#define NUM_SPI 1 +#define NUM_I2C 1 + +#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) + +#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9) + +static const uint8_t SS = 10; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 12; +static const uint8_t SCK = 13; + +static const uint8_t SDA = 18; +static const uint8_t SCL = 19; +static const uint8_t LED_BUILTIN = 13; + +static const uint8_t A0 = 14; +static const uint8_t A1 = 15; +static const uint8_t A2 = 16; +static const uint8_t A3 = 17; +static const uint8_t A4 = 18; +static const uint8_t A5 = 19; +static const uint8_t A6 = 20; +static const uint8_t A7 = 21; + +#endif diff --git a/variants/intel_edu_x/variant.cpp b/variants/intel_edu_x/variant.cpp new file mode 100644 index 00000000..46777ece --- /dev/null +++ b/variants/intel_edu_x/variant.cpp @@ -0,0 +1,186 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +#include "portable.h" + + +/* + * EDU Board pin | GPIO | Label + * ----------------+--------------+------- + * 0 | GPIO_SS[9] | "RX0" + * 1 | GPIO_SS[8] | "TX0" + * 2 | GPIO[18] | "" + * 3 | GPIO_SS[10] | "PWM0" + * 4 | GPIO[19] | "" + * 5 | GPIO_SS[11] | "PWM1" + * 6 | GPIO_SS[12] | "PWM2" + * 7 | GPIO[20] | "" + * 8 | GPIO[16] | "" + * 9 | GPIO_SS[13] | "PWM3" + * 10 | GPIO[0] | "" + * 11 | GPIO[3] | "MOSI" + * 12 | GPIO[1] | "MISO" + * 13 | GPIO[2] | "SCK" + * 14 | GPIO_SS[2] | "A0" + * 15 | GPIO_SS[3] | "A1" + * 16 | GPIO_SS[4] | "A2" + * 17 | GPIO_SS[5] | "A3" + * 18 | GPIO_SS[6] | "A4" + * 19 | GPIO_SS[7] | "A5" +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pins descriptions + */ +PinDescription g_APinDescription[]= +{ + +// gpio port type base soc pin mux mode pwm chan pwm scale + { 1, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 17, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO0 + { 0, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 16, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO1 + { 18, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 52, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO2 + { 2, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 63, GPIO_MUX_MODE, 0, PWM_SCALE_490HZ }, // Arduino IO3 + { 19, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 53, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO4 + { 3, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 64, GPIO_MUX_MODE, 1, PWM_SCALE_980HZ }, // Arduino IO5 + { 4, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 65, GPIO_MUX_MODE, 2, PWM_SCALE_980HZ }, // Arduino IO6 + { 20, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 54, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO7 + { 16, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 43, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO8 + { 5, SS_GPIO_8B1, SS_GPIO, SS_GPIO_8B1_BASE_ADDR, 66, GPIO_MUX_MODE, 3, PWM_SCALE_490HZ }, // Arduino IO9 + { 0, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 0, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO10 + { 3, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 3, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO11 + { 1, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 1, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO12 + { 2, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 2, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO13 + { 2, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 10, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO14 + { 3, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 11, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO15 + { 4, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 12, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO16 + { 5, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 13, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO17 + { 6, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 14, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO18 + { 7, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 15, GPIO_MUX_MODE, INVALID, INVALID }, // Arduino IO19 + +} ; + +#ifdef __cplusplus +} +#endif + +uint32_t sizeof_g_APinDescription; + +#ifdef OUT + +/* + * UART objects + */ +RingBuffer rx_buffer1; +RingBuffer tx_buffer1; + +UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); +void serialEvent() __attribute__((weak)); +void serialEvent() { } + +// IT handlers +void UART_Handler(void) +{ + Serial.IrqHandler(); +} + +// ---------------------------------------------------------------------------- +/* + * USART objects + */ +RingBuffer rx_buffer2; +RingBuffer tx_buffer2; + +USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); +void serialEvent1() __attribute__((weak)); +void serialEvent1() { } + +// IT handlers +void USART0_Handler(void) +{ + Serial1.IrqHandler(); +} + +// ---------------------------------------------------------------------------- + +void serialEventRun(void) +{ + if (Serial.available()) serialEvent(); + if (Serial1.available()) serialEvent1(); +} + +#endif + + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +void variantGpioInit(void) +{ +#define GPIO_CLKENA_POS (31) +#define GPIO_LS_SYNC_POS (0) + + /* Enable SoC GPIO peripheral clock */ + SET_MMIO_BIT((SOC_GPIO_BASE_ADDR+SOC_GPIO_LS_SYNC), GPIO_CLKENA_POS); + SET_MMIO_BIT((SOC_GPIO_BASE_ADDR+SOC_GPIO_LS_SYNC), GPIO_LS_SYNC_POS); + /* Enable SS_GPIO port 0 peripheral clock */ + SET_ARC_BIT((SS_GPIO_8B0_BASE_ADDR+SS_GPIO_LS_SYNC), GPIO_CLKENA_POS); + SET_ARC_BIT((SS_GPIO_8B0_BASE_ADDR+SS_GPIO_LS_SYNC), GPIO_LS_SYNC_POS); + /* Enable SS_GPIO port 1 peripheral clock */ + SET_ARC_BIT((SS_GPIO_8B1_BASE_ADDR+SS_GPIO_LS_SYNC), GPIO_CLKENA_POS); + SET_ARC_BIT((SS_GPIO_8B1_BASE_ADDR+SS_GPIO_LS_SYNC), GPIO_LS_SYNC_POS); + + for (uint8_t pin = 0; pin < NUM_DIGITAL_PINS; pin++) { + PinDescription *p = &g_APinDescription[pin]; + SET_PIN_MODE(p->ulSocPin, p->ulPinMode); + } +} + +void variantPwmInit(void) +{ + /* Enable PWM peripheral clock */ + MMIO_REG_VAL(QRK_CLKGATE_CTRL) |= QRK_CLKGATE_CTRL_PWM_ENABLE; + + /* Select PWM mode, with interrupts masked */ + for (uint8_t i = 0; i < NUM_PWM; i++) { + uint32_t offset = ((i * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_CONTROL); + MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, offset) = QRK_PWM_CONTROL_PWM_OUT | QRK_PWM_CONTROL_INT_MASK | QRK_PWM_CONTROL_MODE_PERIODIC; + } +} + +void initVariant( void ) +{ + /* For now, lets enable clocks for all interfaces we need + * TODO - Consider only enabling as needed later to reduce power consumption + */ + variantGpioInit(); + variantPwmInit(); +} + +#ifdef __cplusplus +} +#endif + diff --git a/variants/intel_edu_x/variant.h b/variants/intel_edu_x/variant.h new file mode 100644 index 00000000..1adf74dd --- /dev/null +++ b/variants/intel_edu_x/variant.h @@ -0,0 +1,122 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_INTEL_EDU_X_ +#define _VARIANT_INTEL_EDU_X_ + +#include "gpio.h" +#include "ss_gpio_iface.h" +#include "soc_gpio.h" +#include "scss_registers.h" + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "Arduino.h" +#include "wiring_digital.h" +#include "pins_arduino.h" +//#ifdef __cplusplus +//#include "UARTClass.h" +//#include "USARTClass.h" +//#endif + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +/* + * LEDs + */ +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN 13 + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +/* + * GPIO + */ +#define GPIO_MUX_MODE QRK_PMUX_SEL_MODEA + +/* + * PWM + */ +#define PWM_FREQUENCY 490 +#define PWM_PERIOD_NS 2048000 +#define PWM_MAX_DUTY_CYCLE 65535 +#define PWM_MIN_DUTY_CYCLE 1 +#define PWM_RESOLUTION 16 +#define PWM_MUX_MODE QRK_PMUX_SEL_MODEB +#define PWM_SCALE_490HZ 0 /* "Standard" Arduino PWM frequency is 490Hz */ +#define PWM_SCALE_980HZ 1 /* Some pins on Arduino boards emit 980Hz PWM */ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +//extern UARTClass Serial; +//extern USARTClass Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL SerialUSB +#define SERIAL_PORT_HARDWARE_OPEN Serial1 +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE1 Serial1 + +#define SS_GPIO 1 +#define SOC_GPIO 2 + +extern uint32_t sizeof_g_APinDescription; + +#endif /* _VARIANT_INTEL_EDU_X_ */ +