diff --git a/release.manifest b/release.manifest index fb398d6..7198306 100644 --- a/release.manifest +++ b/release.manifest @@ -61,7 +61,7 @@ CACHE: /worker.js /monacoworker.js -# ver Wed Nov 16 2022 14:41:22 GMT+0000 (Coordinated Universal Time) +# ver Fri Dec 02 2022 11:44:03 GMT+0000 (Coordinated Universal Time) # target /docs/static/logo.svg diff --git a/target.js b/target.js index dc9f5d5..25277fb 100644 --- a/target.js +++ b/target.js @@ -576,9 +576,10 @@ var pxtTargetBundle = { "ignoreDocsErrors": true, "uploadDocs": true, "versions": { - "branch": "main", - "commits": "https://github.com/letssteam/pxt-lets-steam/commits/f27999bbfa3f7b9efec725065f3f4048147033c9", - "target": "1.0.31", + "branch": "v1.0.32", + "tag": "v1.0.32", + "commits": "https://github.com/letssteam/pxt-lets-steam/commits/ca67d4a99b3f90769325fe37ffb2458c3b894b50", + "target": "1.0.32", "pxt": "7.4.12" }, "blocksprj": { @@ -651,7 +652,7 @@ var pxtTargetBundle = { "pxt-core.d.ts": "/// \n\ninterface Array {\n /**\n * Get or set the length of an array. This number is one more than the index of the last element the array.\n */\n //% shim=Array_::length weight=84\n //% blockId=\"lists_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"arrays\"\n length: number;\n\n /**\n * Append a new element to an array.\n * @param items New elements of the Array.\n */\n //% help=arrays/push\n //% shim=Array_::push weight=50\n //% blockId=\"array_push\" block=\"%list| add value %value| to end\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n push(item: T): void;\n\n /**\n * Concatenates the values with another array.\n * @param arr The other array that is being concatenated with\n */\n //% helper=arrayConcat weight=40\n concat(arr: T[]): T[];\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=45\n //% blockId=\"array_pop\" block=\"get and remove last value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n pop(): T;\n\n /**\n * Reverse the elements in an array. The first array element becomes the last, and the last array element becomes the first.\n */\n //% help=arrays/reverse\n //% helper=arrayReverse weight=10\n //% blockId=\"array_reverse\" block=\"reverse %list\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n reverse(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=30\n //% blockId=\"array_shift\" block=\"get and remove first value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n shift(): T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=25\n //% blockId=\"array_unshift\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n //unshift(...values:T[]): number; //rest is not supported in our compiler yet.\n unshift(value: T): number;\n\n /**\n * Return a section of an array.\n * @param start The beginning of the specified portion of the array. eg: 0\n * @param end The end of the specified portion of the array. eg: 0\n */\n //% help=arrays/slice\n //% helper=arraySlice weight=41 blockNamespace=\"arrays\"\n slice(start?: number, end?: number): T[];\n\n /**\n * Remove elements from an array.\n * @param start The zero-based location in the array from which to start removing elements. eg: 0\n * @param deleteCount The number of elements to remove. eg: 0\n */\n //% helper=arraySplice weight=40\n splice(start: number, deleteCount: number): void;\n\n /**\n * joins all elements of an array into a string and returns this string.\n * @param sep the string separator\n */\n //% helper=arrayJoin weight=40\n join(sep?: string): string;\n\n /**\n * Tests whether at least one element in the array passes the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arraySome weight=40\n some(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Tests whether all elements in the array pass the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayEvery weight=40\n every(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Sort the elements of an array in place and returns the array. The sort is not necessarily stable.\n * @param specifies a function that defines the sort order. If omitted, the array is sorted according to the prmitive type\n */\n //% helper=arraySort weight=40\n sort(callbackfn?: (value1: T, value2: T) => number): T[];\n\n /**\n * Call a defined callback function on each element of an array, and return an array containing the results.\n * @param callbackfn A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayMap weight=40\n map(callbackfn: (value: T, index: number) => U): U[];\n\n /**\n * Call a defined callback function on each element of an array.\n * @param callbackfn A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayForEach weight=40\n forEach(callbackfn: (value: T, index: number) => void): void;\n\n /**\n * Return the elements of an array that meet the condition specified in a callback function.\n * @param callbackfn A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayFilter weight=40\n filter(callbackfn: (value: T, index: number) => boolean): T[];\n\n /**\n * Fills all the elements of an array from a start index to an end index with a static value. The end index is not included.\n */\n //% helper=arrayFill weight=39\n fill(value: T, start?: number, end?: number): T[];\n\n /**\n * Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.\n * @param callbackfn\n */\n //% helper=arrayFind weight=40\n find(callbackfn: (value: T, index: number) => boolean): T;\n\n /**\n * Call the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n * @param callbackfn A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.\n * @param initialValue Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n */\n //% helper=arrayReduce weight=40\n reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;\n\n\n /** Remove the first occurence of an object. Returns true if removed. */\n //% shim=Array_::removeElement weight=48\n removeElement(element: T): boolean;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=47\n //% blockId=\"array_removeat\" block=\"%list| get and remove value at %index\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n removeAt(index: number): T;\n\n /**\n * Insert the value at a particular index, increases length by 1\n * @param index the zero-based position in the list to insert the value, eg: 0\n * @param the value to insert, eg: 0\n */\n //% help=arrays/insert-at\n //% shim=Array_::insertAt weight=20\n //% blockId=\"array_insertAt\" block=\"%list| insert at %index| value %value\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n insertAt(index: number, value: T): void;\n\n /**\n * Return the index of the first occurrence of a value in an array.\n * @param item The value to locate in the array.\n * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n */\n //% help=arrays/index-of\n //% shim=Array_::indexOf weight=40\n //% blockId=\"array_indexof\" block=\"%list| find index of %value\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n indexOf(item: T, fromIndex?: number): number;\n\n /**\n * Get the value at a particular index\n * @param index the zero-based position in the list of the item, eg: 0\n */\n //% help=arrays/get\n //% shim=Array_::getAt weight=85\n get(index: number): T;\n\n /**\n * Store a value at a particular index\n * @param index the zero-based position in the list to store the value, eg: 0\n * @param value the value to insert, eg: 0\n */\n //% help=arrays/set\n //% shim=Array_::setAt weight=84\n set(index: number, value: T): void;\n\n /**\n * Return a random value from the array\n */\n //% help=arrays/pick-random\n //% helper=arrayPickRandom weight=25\n //% blockId=\"array_pickRandom\" block=\"get random value from %list\"\n //% blockNamespace=\"arrays\"\n //% group=\"Read\"\n _pickRandom(): T;\n\n [n: number]: T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=24\n //% blockId=\"array_unshift_statement\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.unshift\"\n //% group=\"Modify\"\n _unshiftStatement(value: T): void;\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=44\n //% blockId=\"array_pop_statement\" block=\"remove last value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.pop\"\n //% group=\"Modify\"\n _popStatement(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=29\n //% blockId=\"array_shift_statement\" block=\"remove first value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.shift\"\n //% group=\"Modify\"\n _shiftStatement(): void;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=14\n //% blockId=\"array_removeat_statement\" block=\"%list| remove value at %index\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.removeAt\"\n //% group=\"Modify\"\n _removeAtStatement(index: number): void;\n}\n\ndeclare interface String {\n // This block is currently disabled in favor of the built-in Blockly \"Create text with\" block, which compiles to \"\" + \"\"\n // Add % sign back to the block annotation to re-enable\n /**\n * Returns a string that contains the concatenation of two or more strings.\n * @param other The string to append to the end of the string.\n */\n //% shim=String_::concat weight=49\n //% blockId=\"string_concat\" blockNamespace=\"text\"\n // block=\"join %list=text|%other\"\n concat(other: string): string;\n\n /**\n * Return the character at the specified index.\n * @param index The zero-based index of the desired character.\n */\n //% shim=String_::charAt weight=48\n //% help=text/char-at\n //% blockId=\"string_get\" block=\"char from %this=text|at %pos\" blockNamespace=\"text\"\n charAt(index: number): string;\n\n /** Returns the length of a String object. */\n //% property shim=String_::length weight=47\n //% blockId=\"text_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"text\"\n length: number;\n\n /**\n * Return the Unicode value of the character at the specified location.\n * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\n */\n //% shim=String_::charCodeAt\n charCodeAt(index: number): number;\n\n /**\n * See how the order of characters in two strings is different (in ASCII encoding).\n * @param that String to compare to target string\n */\n //% shim=String_::compare\n //% help=text/compare\n //% blockId=\"string_compare\" block=\"compare %this=text| to %that\" blockNamespace=\"text\"\n compare(that: string): number;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param length number of characters to extract, eg: 10\n */\n //% helper=stringSubstr\n //% help=text/substr\n //% blockId=\"string_substr\" block=\"substring of %this=text|from %start|of length %length\" blockNamespace=\"text\"\n substr(start: number, length?: number): string;\n\n /**\n * Return the current string with the first occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplace\n replace(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return the current string with each occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplaceAll\n replaceAll(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param end one-past-last character index\n */\n //% helper=stringSlice\n slice(start: number, end?: number): string;\n\n /** Returns a value indicating if the string is empty */\n //% helper=stringEmpty\n //% help=text/is-empty\n //% blockId=\"string_isempty\" blockNamespace=\"text\"\n //% block=\"%this=text| is empty\"\n isEmpty(): boolean;\n\n /**\n * Returns the position of the first occurrence of a specified value in a string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::indexOf\n //% help=text/index-of\n //% blockId=\"string_indexof\" blockNamespace=\"text\"\n //% block=\"%this=text|find index of %searchValue\"\n indexOf(searchValue: string, start?: number): number;\n\n /**\n * Determines whether a string contains the characters of a specified string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::includes\n //% help=text/includes\n //% blockId=\"string_includes\" blockNamespace=\"text\"\n //% block=\"%this=text|includes %searchValue\"\n includes(searchValue: string, start?: number): boolean;\n\n /**\n * Splits the string according to the separators\n * @param separator\n * @param limit\n */\n //% helper=stringSplit\n //% help=text/split\n //% blockId=\"string_split\" blockNamespace=\"text\"\n //% block=\"split %this=text|at %separator\"\n split(separator?: string, limit?: number): string[];\n\n /**\n * Return a substring of the current string with whitespace removed from both ends\n */\n //% helper=stringTrim\n trim(): string;\n\n /**\n * Converts the string to upper case characters.\n */\n //% helper=stringToUpperCase\n //% help=text/to-upper-case\n toUpperCase(): string;\n\n /**\n * Converts the string to lower case characters.\n */\n //% helper=stringToLowerCase\n //% help=text/to-lower-case\n toLowerCase(): string;\n\n [index: number]: string;\n}\n\n/**\n * Convert a string to a number.\n * @param s A string to convert into a number. eg: 123\n */\n//% shim=String_::toNumber\n//% help=text/parse-float\n//% blockId=\"string_parsefloat\" block=\"parse to number %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\ndeclare function parseFloat(text: string): number;\n\n/**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n//% blockId=\"device_random\" block=\"pick random %min|to %limit\"\n//% blockNamespace=\"Math\"\n//% help=math/randint\n//% shim=Math_::randomRange\ndeclare function randint(min: number, max: number): number;\n\ninterface Object { }\ninterface Function {\n __assignableToFunction: Function;\n}\ninterface IArguments {\n __assignableToIArguments: IArguments;\n}\ninterface RegExp {\n __assignableToRegExp: RegExp;\n}\ntype TemplateStringsArray = Array;\n\ntype uint8 = number;\ntype uint16 = number;\ntype uint32 = number;\ntype int8 = number;\ntype int16 = number;\ntype int32 = number;\n\n\ndeclare interface Boolean {\n /**\n * Returns a string representation of an object.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Combine, split, and search text strings.\n*/\n//% blockNamespace=\"text\"\ndeclare namespace String {\n\n /**\n * Make a string from the given ASCII character code.\n */\n //% help=math/from-char-code\n //% shim=String_::fromCharCode weight=1\n //% blockNamespace=\"text\" blockId=\"stringFromCharCode\" block=\"text from char code %code\"\n function fromCharCode(code: number): string;\n}\n\ndeclare interface Number {\n /**\n * Returns a string representation of a number.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Add, remove, and replace items in lists.\n*/\n//% blockNamespace=\"Arrays\"\ndeclare namespace Array {\n /**\n * Check if a given object is an array.\n */\n //% shim=Array_::isArray\n function isArray(obj: any): boolean;\n}\n\ndeclare namespace Object {\n /**\n * Return the field names in an object.\n */\n //% shim=pxtrt::keysOf\n function keys(obj: any): string[];\n}\n\n/**\n * More complex operations with numbers.\n*/\ndeclare namespace Math {\n /**\n * Returns the value of a base expression taken to a specified power.\n * @param x The base value of the expression.\n * @param y The exponent value of the expression.\n */\n //% shim=Math_::pow\n function pow(x: number, y: number): number;\n\n /**\n * Returns a pseudorandom number between 0 and 1.\n */\n //% shim=Math_::random\n //% help=math/random\n function random(): number;\n\n /**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n //% blockId=\"device_random_deprecated\" block=\"pick random %min|to %limit\"\n //% help=math/random-range deprecated\n //% shim=Math_::randomRange\n function randomRange(min: number, max: number): number;\n\n /**\n * Returns the natural logarithm (base e) of a number.\n * @param x A number\n */\n //% shim=Math_::log\n //% help=math\n function log(x: number): number;\n\n /**\n * Returns returns ``e^x``.\n * @param x A number\n */\n //% shim=Math_::exp\n //% help=math\n function exp(x: number): number;\n\n /**\n * Returns the sine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::sin\n //% help=math/trigonometry\n function sin(x: number): number;\n\n /**\n * Returns the cosine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::cos\n //% help=math/trigonometry\n function cos(x: number): number;\n\n /**\n * Returns the tangent of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::tan\n //% help=math/trigonometry\n function tan(x: number): number;\n\n /**\n * Returns the arcsine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::asin\n //% help=math/trigonometry\n function asin(x: number): number;\n\n /**\n * Returns the arccosine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::acos\n //% help=math/trigonometry\n function acos(x: number): number;\n\n /**\n * Returns the arctangent (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::atan\n //% help=math/trigonometry\n function atan(x: number): number;\n\n /**\n * Returns the arctangent of the quotient of its arguments.\n * @param y A number\n * @param x A number\n */\n //% shim=Math_::atan2\n //% help=math/trigonometry\n function atan2(y: number, x: number): number;\n\n /**\n * Returns the square root of a number.\n * @param x A numeric expression.\n */\n //% shim=Math_::sqrt\n //% help=math\n function sqrt(x: number): number;\n\n /**\n * Returns the smallest number greater than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::ceil\n //% help=math\n function ceil(x: number): number;\n\n /**\n * Returns the greatest number less than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::floor\n //% help=math\n function floor(x: number): number;\n\n /**\n * Returns the number with the decimal part truncated.\n * @param x A numeric expression.\n */\n //% shim=Math_::trunc\n //% help=math\n function trunc(x: number): number;\n\n /**\n * Returns a supplied numeric expression rounded to the nearest number.\n * @param x The value to be rounded to the nearest number.\n */\n //% shim=Math_::round\n //% help=math\n function round(x: number): number;\n\n /**\n * Returns the value of integer signed 32 bit multiplication of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::imul\n //% help=math\n function imul(x: number, y: number): number;\n\n /**\n * Returns the value of integer signed 32 bit division of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::idiv\n //% help=math\n function idiv(x: number, y: number): number;\n}\n\ndeclare namespace control {\n //% shim=_control::_onCodeStart\n export function _onCodeStart(arg: any): void;\n\n //% shim=_control::_onCodeStop\n export function _onCodeStop(arg: any): void;\n}", "pxt-helpers.ts": "type Action = () => void;\n\n/**\n * Constant representing Not-A-Number.\n */\nconst NaN = 0 / 0\n\n/**\n * Constant representing positive infinity.\n */\nconst Infinity = 1 / 0\n\nfunction isNaN(x: number) {\n x = +x // convert to number\n return x !== x\n}\n\nnamespace Number {\n /**\n * Check if a given value is of type Number and it is a NaN.\n */\n export function isNaN(x: any): boolean {\n return typeof x == \"number\" && x !== x\n }\n}\n\n/**\n * A dictionary from string key to string values\n */\ninterface StringMap {\n [index: string]: string;\n}\n\n/**\n * Convert a string to an integer.\n * @param text A string to convert into an integral number. eg: \"123\"\n * @param radix optional A value between 2 and 36 that specifies the base of the number in text.\n * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n * All other strings are considered decimal.\n */\n//% help=text/parse-int\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\n//% blockHidden=1\nfunction parseInt(text: string, radix?: number): number {\n // roughly based on https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2\n // with some consideration for avoiding unnecessary slices where easy\n if (!text || (radix != null && (radix < 2 || radix > 36)))\n return NaN;\n\n let start = 0;\n while (start < text.length && helpers.isWhitespace(text.charCodeAt(start)))\n ++start;\n\n if (start === text.length)\n return NaN;\n\n const numberOffset = 48; // 0\n const numCount = 10;\n const letterOffset = 97; // a\n const letterCount = 26;\n const lowerCaseMask = 0x20;\n\n let sign = 1;\n switch (text.charAt(start)) {\n case \"-\":\n sign = -1;\n // fallthrough\n case \"+\":\n ++start;\n }\n\n if ((!radix || radix == 16)\n && \"0\" === text[start]\n && (\"x\" === text[start + 1] || \"X\" === text[start + 1])) {\n radix = 16;\n start += 2;\n } else if (!radix) {\n radix = 10;\n }\n\n let output = 0;\n let hasDigit = false;\n for (let i = start; i < text.length; ++i) {\n const code = text.charCodeAt(i) | lowerCaseMask;\n let val: number = undefined;\n\n if (code >= numberOffset && code < numberOffset + numCount)\n val = code - numberOffset;\n else if (code >= letterOffset && code < letterOffset + letterCount)\n val = numCount + code - letterOffset;\n\n if (val == undefined || val >= radix) {\n if (!hasDigit) {\n return NaN;\n }\n break;\n }\n hasDigit = true;\n output = output * radix + val;\n }\n\n return sign * output;\n}\n\nnamespace helpers {\n export function arrayFill(O: T[], value: T, start?: number, end?: number) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n // Steps 3-5.\n const len = O.length >>> 0;\n\n // Steps 6-7.\n const relativeStart = start === undefined ? 0 : start >> 0;\n\n // Step 8.\n let k = relativeStart < 0 ?\n Math.max(len + relativeStart, 0) :\n Math.min(relativeStart, len);\n\n // Steps 9-10.\n const relativeEnd = end === undefined ? len : end >> 0;\n\n // Step 11.\n const final = relativeEnd < 0 ?\n Math.max(len + relativeEnd, 0) :\n Math.min(relativeEnd, len);\n\n // Step 12.\n while (k < final) {\n O[k] = value;\n k++;\n }\n\n // Step 13.\n return O;\n }\n\n export function arraySplice(arr: T[], start: number, len: number) {\n if (start < 0) {\n return;\n }\n for (let i = 0; i < len; ++i) {\n arr.removeAt(start)\n }\n }\n\n export function arrayReverse(arr: T[]): void {\n let len = arr.length;\n for (let i = 0; i < len / 2; i++) {\n swap(arr, i, len - i - 1);\n }\n }\n\n export function arrayShift(arr: T[]): T {\n return arr.removeAt(0);\n }\n\n export function arrayJoin(arr: T[], sep?: string): string {\n if (sep === undefined || sep === null) {\n sep = \",\";\n }\n\n let r = \"\";\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n if (i > 0 && sep)\n r += sep;\n r += (arr[i] === undefined || arr[i] === null) ? \"\" : arr[i];\n }\n return r;\n }\n\n /*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n export function arrayUnshift(arr: T[], ...values: T[]) : number {\n for(let i = values.length; i > 0; --i) {\n arr.insertAt(0, values[i - 1]);\n }\n return arr.length;\n }\n */\n export function arrayUnshift(arr: T[], value: T): number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap(arr: T[], i: number, j: number): void {\n let temp: T = arr[i];\n arr[i] = arr[j];\n arr[j] = temp;\n }\n\n function sortHelper(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (arr.length <= 0 || !callbackfn) {\n return arr;\n }\n let len = arr.length;\n // simple selection sort.\n for (let i = 0; i < len - 1; ++i) {\n for (let j = i + 1; j < len; ++j) {\n if (callbackfn(arr[i], arr[j]) > 0) {\n swap(arr, i, j);\n }\n }\n }\n return arr;\n }\n\n export function arraySort(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (!callbackfn && arr.length > 1) {\n callbackfn = (a, b) => {\n // default is sort as if the element were a string, with null < undefined\n const aIsUndef = a === undefined;\n const bIsUndef = b === undefined;\n if (aIsUndef && bIsUndef) return 0;\n else if (aIsUndef) return 1;\n else if (bIsUndef) return -1;\n\n const aIsNull = a === null;\n const bIsNull = b === null;\n if (aIsNull && bIsNull) return 0;\n else if (aIsNull) return 1;\n else if (bIsNull) return -1;\n\n return (a + \"\").compare(b + \"\");\n }\n }\n return sortHelper(arr, callbackfn);\n }\n\n export function arrayMap(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n let res: U[] = []\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n res.push(callbackfn(arr[i], i))\n }\n return res\n }\n\n export function arraySome(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (callbackfn(arr[i], i))\n return true;\n return false;\n }\n\n export function arrayEvery(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (!callbackfn(arr[i], i))\n return false;\n return true;\n }\n\n export function arrayForEach(arr: T[], callbackfn: (value: T, index: number) => void): void {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n callbackfn(arr[i], i);\n }\n }\n\n export function arrayFilter(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n let res: T[] = []\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) res.push(v)\n }\n return res\n }\n\n export function arrayFind(arr: T[], callbackfn: (value: T, index: number) => boolean): T {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) return v;\n }\n return undefined;\n }\n\n export function arrayReduce(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n initialValue = callbackfn(initialValue, arr[i], i)\n }\n return initialValue\n }\n\n export function arrayConcat(arr: T[], otherArr: T[]): T[] {\n let out: T[] = [];\n for (let value of arr) {\n out.push(value);\n }\n for (let value of otherArr) {\n out.push(value);\n }\n return out;\n }\n\n export function arrayPickRandom(arr: T[]): T {\n return arr[Math.randomRange(0, arr.length - 1)];\n }\n\n export function arraySlice(arr: T[], start?: number, end?: number): T[] {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\n const res: T[] = [];\n const len = arr.length;\n\n if (start === undefined)\n start = 0;\n else if (start < 0)\n start = Math.max(len + start, 0);\n\n if (start > len)\n return res;\n\n if (end === undefined)\n end = len;\n else if (end < 0)\n end = len + end;\n\n if (end > len)\n end = len;\n\n for (let i = start; i < end; ++i) {\n res.push(arr[i]);\n }\n return res;\n }\n\n export function stringReplace(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const ind = s.indexOf(toReplace);\n if (ind == -1)\n return s;\n\n const begin = s.slice(0, ind);\n const end = s.slice(ind + toReplace.length);\n\n if (typeof replacer == \"string\" || !replacer) {\n return begin + replacer + end;\n } else {\n return begin + replacer(toReplace) + end;\n }\n }\n\n export function stringReplaceAll(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const split = s.split(toReplace);\n const empty = toReplace.isEmpty();\n\n let output = (empty ? applyReplace(toReplace, replacer) : \"\");\n\n if (split.length) {\n output += split[0];\n }\n\n for (let i = 1; i < split.length; ++i) {\n output += applyReplace(toReplace, replacer) + split[i];\n }\n\n if (!s.isEmpty() && empty) {\n output += applyReplace(toReplace, replacer);\n }\n\n return output;\n\n function applyReplace(r: string, replacer: string | ((sub: string) => string)): string {\n if (typeof replacer == \"string\" || !replacer) {\n return replacer as string;\n } else {\n return replacer(r);\n }\n }\n }\n\n //% shim=String_::substr\n declare function stringSubstrHelper(s: string, start: number, length?: number): string;\n\n export function stringSubstr(s: string, start: number, length?: number): string {\n length = length === undefined ? s.length : length || 0;\n return stringSubstrHelper(s, start, length);\n }\n\n export function stringSlice(s: string, start: number, end?: number): string {\n const len = s.length;\n\n if (start < 0) {\n start = Math.max(len + start, 0);\n }\n\n if (end === undefined) {\n end = len;\n } else if (end === null) {\n end = 0;\n }\n\n if (end < 0) {\n end = len + end;\n }\n\n return stringSubstrHelper(s, start, end - start);\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleUpperCase())\n export function stringToUpperCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (97 <= c && c <= 122) {\n r += s.slice(prev, i) + String.fromCharCode(c - 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleLowerCase())\n export function stringToLowerCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (65 <= c && c <= 90) {\n r += s.slice(prev, i) + String.fromCharCode(c + 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n export function stringSplit(S: string, separator?: string, limit?: number): string[] {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.split\n const A: string[] = [];\n let lim = 0;\n if (limit === undefined)\n lim = (1 << 29) - 1; // spec says 1 << 53, leaving it at 29 for constant folding\n else if (limit < 0)\n lim = 0;\n else\n lim = limit | 0;\n const s = S.length;\n let p = 0;\n const R = separator;\n if (lim == 0)\n return A;\n if (separator === undefined) {\n A[0] = S;\n return A;\n }\n if (s == 0) {\n let z = splitMatch(S, 0, R);\n if (z > -1) return A;\n A[0] = S;\n return A;\n }\n let T: string;\n let q = p;\n while (q != s) {\n let e = splitMatch(S, q, R);\n if (e < 0) q++;\n else {\n if (e == p) q++;\n else {\n T = stringSlice(S, p, q);\n A.push(T);\n if (A.length == lim) return A;\n p = e;\n q = p;\n }\n }\n }\n T = stringSlice(S, p, q);\n A.push(T);\n return A;\n }\n\n function splitMatch(S: string, q: number, R: string): number {\n const r = R.length;\n const s = S.length;\n if (q + r > s) return -1;\n for (let i = 0; i < r; ++i) {\n if (S[q + i] != R[i])\n return -1;\n }\n return q + r;\n }\n\n export function stringTrim(s: string): string {\n let start = 0;\n let end = s.length - 1;\n\n while (start <= end && isWhitespace(s.charCodeAt(start)))\n ++start;\n\n while (end > start && isWhitespace(s.charCodeAt(end)))\n --end;\n return s.slice(start, end + 1);\n }\n\n export function isWhitespace(c: number): boolean {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-white-space\n switch (c) {\n case 0x0009: // character tab\n case 0x000B: // line tab\n case 0x000C: // form feed\n case 0x0020: // space\n case 0x00A0: // no-break space\n case 0xFEFF: // zero width no break space\n case 0x000A: // line feed\n case 0x000D: // carriage return\n case 0x2028: // line separator\n case 0x2029: // paragraph separator\n return true;\n default:\n return false;\n }\n }\n\n export function stringEmpty(S: string): boolean {\n return !S;\n }\n}\n\nnamespace Math {\n export function clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n }\n\n /**\n * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\n * For example, the absolute value of -5 is the same as the absolute value of 5.\n * @param x A numeric expression for which the absolute value is needed.\n */\n //% help=math/abs\n export function abs(x: number): number {\n return x < 0 ? -x : x;\n }\n\n /**\n * Returns the sign of the x, indicating whether x is positive, negative or zero.\n * @param x The numeric expression to test\n */\n export function sign(x: number): number {\n if (x == 0) return 0;\n if (x > 0) return 1;\n return -1;\n }\n\n /**\n * Returns the larger of two supplied numeric expressions.\n */\n //% help=math/max\n export function max(a: number, b: number): number {\n if (a >= b) return a;\n return b;\n }\n\n /**\n * Returns the smaller of two supplied numeric expressions.\n */\n //% help=math/min\n export function min(a: number, b: number): number {\n if (a <= b) return a;\n return b;\n }\n\n /**\n * Rounds ``x`` to a number with the given number of ``digits``\n * @param x the number to round\n * @param digits the number of resulting digits\n */\n //%\n export function roundWithPrecision(x: number, digits: number): number {\n digits = digits | 0;\n // invalid digits input\n if (digits <= 0) return Math.round(x);\n if (x == 0) return 0;\n let r = 0;\n do {\n const d = Math.pow(10, digits);\n r = Math.round(x * d) / d;\n digits++;\n } while (r == 0 && digits < 21);\n return r;\n }\n}\n\n\n//% blockHidden=1\nnamespace __internal {\n /**\n * A shim to render a boolean as a down/up toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleDownUp block=\"%down\"\n //% down.fieldEditor=toggledownup\n //% down.fieldOptions.decompileLiterals=true\n export function __downUp(down: boolean): boolean {\n return down;\n }\n\n /**\n * A shim to render a boolean as a up/down toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleUpDown block=\"%up\"\n //% up.fieldEditor=toggleupdown\n //% up.fieldOptions.decompileLiterals=true\n export function __upDown(up: boolean): boolean {\n return up;\n }\n\n /**\n * A shim to render a boolean as a high/low toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleHighLow block=\"%high\"\n //% high.fieldEditor=togglehighlow\n //% high.fieldOptions.decompileLiterals=true\n export function __highLow(high: boolean): boolean {\n return high;\n }\n\n /**\n * A shim to render a boolean as a on/off toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleOnOff block=\"%on\"\n //% on.fieldEditor=toggleonoff\n //% on.fieldOptions.decompileLiterals=true\n export function __onOff(on: boolean): boolean {\n return on;\n }\n\n /**\n * A shim to render a boolean as a yes/no toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleYesNo block=\"%yes\"\n //% yes.fieldEditor=toggleyesno\n //% yes.fieldOptions.decompileLiterals=true\n export function __yesNo(yes: boolean): boolean {\n return yes;\n }\n\n /**\n * A shim to render a boolean as a win/lose toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleWinLose block=\"%win\"\n //% win.fieldEditor=togglewinlose\n //% win.fieldOptions.decompileLiterals=true\n export function __winLose(win: boolean): boolean {\n return win;\n }\n\n /**\n * Get the color wheel field editor\n * @param color color, eg: #ff0000\n */\n //% blockId=colorNumberPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colornumber\" value.fieldOptions.decompileLiterals=true\n //% value.defl='#ff0000'\n //% value.fieldOptions.colours='[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]'\n //% value.fieldOptions.columns=4 value.fieldOptions.className='rgbColorPicker'\n export function __colorNumberPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n export function __colorWheelPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor using HSV values\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelHsvPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n //% value.fieldOptions.channel=hsvfast\n export function __colorWheelHsvPicker(value: number) {\n return value;\n }\n\n /**\n * A speed picker\n * @param speed the speed, eg: 50\n */\n //% blockId=speedPicker block=\"%speed\" shim=TD_ID\n //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1\n export function __speedPicker(speed: number): number {\n return speed;\n }\n\n /**\n * A turn ratio picker\n * @param turnratio the turn ratio, eg: 0\n */\n //% blockId=turnRatioPicker block=\"%turnratio\" shim=TD_ID\n //% turnratio.fieldEditor=\"turnratio\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1\n export function __turnRatioPicker(turnratio: number): number {\n return turnratio;\n }\n\n /**\n * A field editor that displays a protractor\n */\n //% blockId=protractorPicker block=\"%angle\"\n //% shim=TD_ID\n //% angle.fieldEditor=protractor\n //% angle.fieldOptions.decompileLiterals=1\n //% colorSecondary=\"#FFFFFF\"\n //% blockHidden=1\n export function __protractor(angle: number) {\n return angle;\n }\n\n /**\n * Get the time field editor\n * @param ms time duration in milliseconds, eg: 500, 1000\n */\n //% blockId=timePicker block=\"%ms\"\n //% blockHidden=true shim=TD_ID\n //% colorSecondary=\"#FFFFFF\"\n //% ms.fieldEditor=\"numberdropdown\" ms.fieldOptions.decompileLiterals=true\n //% ms.fieldOptions.data='[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]'\n export function __timePicker(ms: number): number {\n return ms;\n }\n}\n", "pxt.cpp": "#include \"pxtbase.h\"\n\nusing namespace std;\n\nnamespace pxt {\n\nAction mkAction(int totallen, RefAction *act) {\n check(getVTable(act)->classNo == BuiltInType::RefAction, PANIC_INVALID_BINARY_HEADER, 1);\n#ifdef PXT_VM\n check(act->initialLen <= totallen, PANIC_INVALID_BINARY_HEADER, 13);\n#endif\n\n if (totallen == 0) {\n return (TValue)act; // no closure needed\n }\n\n void *ptr = gcAllocate(sizeof(RefAction) + totallen * sizeof(void *));\n RefAction *r = new (ptr) RefAction();\n r->len = totallen;\n#ifdef PXT_VM\n r->numArgs = act->numArgs;\n r->initialLen = act->initialLen;\n r->flags = 0;\n#endif\n r->func = act->func;\n memset(r->fields, 0, r->len * sizeof(void *));\n\n MEMDBG(\"mkAction: start=%p => %p\", act, r);\n\n return (Action)r;\n}\n\nRefRecord *mkClassInstance(VTable *vtable) {\n intcheck(vtable->methods[0] == &RefRecord_destroy, PANIC_SIZE, 3);\n // intcheck(vtable->methods[1] == &RefRecord_print, PANIC_SIZE, 4);\n\n void *ptr = gcAllocate(vtable->numbytes);\n RefRecord *r = new (ptr) RefRecord(vtable);\n memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));\n MEMDBG(\"mkClass: vt=%p => %p\", vtable, r);\n return r;\n}\n\nTValue RefRecord::ld(int idx) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 1);\n return fields[idx];\n}\n\nTValue RefRecord::ldref(int idx) {\n // DMESG(\"LD %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 2);\n return fields[idx];\n}\n\nvoid RefRecord::st(int idx, TValue v) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 3);\n fields[idx] = v;\n}\n\nvoid RefRecord::stref(int idx, TValue v) {\n // DMESG(\"ST %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 4);\n fields[idx] = v;\n}\n\nvoid RefObject::destroyVT() {\n ((RefObjectMethod)getVTable(this)->methods[0])(this);\n}\n\n//%\nvoid deleteRefObject(RefObject *obj) {\n obj->destroyVT();\n}\n\nvoid RefObject::printVT() {\n ((RefObjectMethod)getVTable(this)->methods[1])(this);\n}\n\nvoid RefRecord_destroy(RefRecord *) {}\n\nvoid RefRecord_print(RefRecord *r) {\n DMESG(\"RefRecord %p size=%d bytes\", r, getVTable(r)->numbytes);\n}\n\nvoid Segment::set(unsigned i, TValue value) {\n if (i < size) {\n data[i] = value;\n } else if (i < Segment::MaxSize) {\n growByMin(i + 1);\n data[i] = value;\n } else {\n return;\n }\n if (length <= i) {\n length = i + 1;\n }\n\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::set\");\n this->print();\n#endif\n\n return;\n}\n\nstatic inline int growthFactor(int size) {\n if (size == 0) {\n return 4;\n }\n if (size < 64) {\n return size * 2; // Double\n }\n if (size < 512) {\n return size * 5 / 3; // Grow by 1.66 rate\n }\n // Grow by constant rate\n if ((unsigned)size + 256 < Segment::MaxSize)\n return size + 256;\n else\n return Segment::MaxSize;\n}\n\nvoid LLSegment::setLength(unsigned newLen) {\n if (newLen > Segment::MaxSize)\n return;\n\n if (newLen > size) {\n int newSize = growthFactor(size);\n if (newSize < (int)newLen)\n newSize = newLen;\n\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(xmalloc(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size) {\n memcpy(tmp, data, size * sizeof(TValue));\n }\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n // free older segment;\n xfree(data);\n\n data = tmp;\n size = newSize;\n } else if (newLen < length) {\n memset(data + newLen, 0, (length - newLen) * sizeof(TValue));\n }\n\n length = newLen;\n}\n\nvoid LLSegment::set(unsigned idx, TValue v) {\n if (idx >= Segment::MaxSize)\n return;\n if (idx >= length)\n setLength(idx + 1);\n data[idx] = v;\n}\n\nTValue LLSegment::pop() {\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = 0;\n return value;\n }\n return 0;\n}\n\nvoid LLSegment::destroy() {\n length = size = 0;\n xfree(data);\n data = nullptr;\n}\n\nvoid Segment::growByMin(ramint_t minSize) {\n ramint_t newSize = max(minSize, (ramint_t)growthFactor(size));\n\n if (size < newSize) {\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(gcAllocateArray(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size)\n memcpy(tmp, data, size * sizeof(TValue));\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n data = tmp;\n size = newSize;\n\n#ifdef DEBUG_BUILD\n DMESG(\"growBy - after reallocation\");\n this->print();\n#endif\n }\n // else { no shrinking yet; }\n return;\n}\n\nvoid Segment::ensure(ramint_t newSize) {\n if (newSize < size) {\n return;\n }\n growByMin(newSize);\n}\n\nvoid Segment::setLength(unsigned newLength) {\n if (newLength > size) {\n ensure(newLength);\n }\n length = newLength;\n return;\n}\n\nTValue Segment::pop() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::pop\");\n this->print();\n#endif\n\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = Segment::DefaultValue;\n return value;\n }\n return Segment::DefaultValue;\n}\n\n// this function removes an element at index i and shifts the rest of the elements to\n// left to fill the gap\nTValue Segment::remove(unsigned i) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::remove index:%d\", i);\n this->print();\n#endif\n if (i < length) {\n // value to return\n TValue ret = data[i];\n if (i + 1 < length) {\n // Move the rest of the elements to fill in the gap.\n memmove(data + i, data + i + 1, (length - i - 1) * sizeof(void *));\n }\n length--;\n data[length] = Segment::DefaultValue;\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::remove index:%d\", i);\n this->print();\n#endif\n return ret;\n }\n return Segment::DefaultValue;\n}\n\n// this function inserts element value at index i by shifting the rest of the elements right.\nvoid Segment::insert(unsigned i, TValue value) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::insert index:%d value:%d\", i, value);\n this->print();\n#endif\n\n if (i < length) {\n ensure(length + 1);\n\n // Move the rest of the elements to fill in the gap.\n memmove(data + i + 1, data + i, (length - i) * sizeof(void *));\n\n data[i] = value;\n length++;\n } else {\n // This is insert beyond the length, just call set which will adjust the length\n set(i, value);\n }\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::insert index:%d\", i);\n this->print();\n#endif\n}\n\nvoid Segment::print() {\n DMESG(\"Segment: %p, length: %d, size: %d\", data, (unsigned)length, (unsigned)size);\n for (unsigned i = 0; i < size; i++) {\n DMESG(\"-> %d\", (unsigned)(uintptr_t)data[i]);\n }\n}\n\nvoid Segment::destroy() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::destroy\");\n this->print();\n#endif\n length = size = 0;\n data = nullptr;\n}\n\nPXT_VTABLE_CTOR(RefCollection) {}\n\nvoid RefCollection::destroy(RefCollection *t) {\n t->head.destroy();\n}\n\nvoid RefCollection::print(RefCollection *t) {\n DMESG(\"RefCollection %p size=%d\", t, t->head.getLength());\n t->head.print();\n}\n\nPXT_VTABLE(RefAction, ValType::Function)\nRefAction::RefAction() : PXT_VTABLE_INIT(RefAction) {}\n\n// fields[] contain captured locals\nvoid RefAction::destroy(RefAction *t) {}\n\nvoid RefAction::print(RefAction *t) {\n#ifdef PXT_VM\n DMESG(\"RefAction %p pc=%X size=%d\", t, (uint32_t)t->func, t->len);\n#else\n DMESG(\"RefAction %p pc=%X size=%d\", t, (const uint8_t *)t->func - (const uint8_t *)bytecode,\n t->len);\n#endif\n}\n\nPXT_VTABLE_CTOR(RefRefLocal) {\n v = 0;\n}\n\nvoid RefRefLocal::print(RefRefLocal *t) {\n DMESG(\"RefRefLocal %p v=%p\", t, (void *)t->v);\n}\n\nvoid RefRefLocal::destroy(RefRefLocal *t) {\n decr(t->v);\n}\n\nPXT_VTABLE_CTOR(RefMap) {}\n\nvoid RefMap::destroy(RefMap *t) {\n t->keys.destroy();\n t->values.destroy();\n}\n\nint RefMap::findIdx(String key) {\n auto len = keys.getLength();\n auto data = (String *)keys.getData();\n\n // fast path\n for (unsigned i = 0; i < len; ++i) {\n if (data[i] == key)\n return i;\n }\n\n // slow path\n auto keylen = key->getUTF8Size();\n auto keydata = key->getUTF8Data();\n for (unsigned i = 0; i < len; ++i) {\n auto s = data[i];\n if (s->getUTF8Size() == keylen && memcmp(keydata, s->getUTF8Data(), keylen) == 0)\n return i;\n }\n\n return -1;\n}\n\nvoid RefMap::print(RefMap *t) {\n DMESG(\"RefMap %p size=%d\", t, t->keys.getLength());\n}\n\nvoid debugMemLeaks() {}\n\nvoid error(PXT_PANIC code, int subcode) {\n DMESG(\"Error: %d [%d]\", code, subcode);\n target_panic(code);\n}\n\n#ifndef PXT_VM\nuint16_t *bytecode;\n#endif\nTValue *globals;\n\nvoid checkStr(bool cond, const char *msg) {\n if (!cond) {\n while (true) {\n // uBit.display.scroll(msg, 100);\n // uBit.sleep(100);\n }\n }\n}\n\n#ifdef PXT_VM\nint templateHash() {\n return *(int*)&vmImg->infoHeader->hexHash;\n}\n\nint programHash() {\n return *(int*)&vmImg->infoHeader->programHash;\n}\n\nint getNumGlobals() {\n return (int)vmImg->infoHeader->allocGlobals;\n}\n\nString programName() {\n return mkString((char *)vmImg->infoHeader->name);\n}\n#else\nint templateHash() {\n return ((int *)bytecode)[4];\n}\n\nint programHash() {\n return ((int *)bytecode)[6];\n}\n\nint getNumGlobals() {\n return bytecode[16];\n}\n\nString programName() {\n return ((String *)bytecode)[15];\n}\n#endif\n\n#ifndef PXT_VM\nvoid variantNotSupported(const char *v) {\n DMESG(\"variant not supported: %s\", v);\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n}\n\nvoid exec_binary(unsigned *pc) {\n // XXX re-enable once the calibration code is fixed and [editor/embedded.ts]\n // properly prepends a call to [internal_main].\n // ::touch_develop::internal_main();\n\n // unique group for radio based on source hash\n // ::touch_develop::micro_bit::radioDefaultGroup = programHash();\n\n unsigned ver = *pc++;\n checkStr(ver == 0x4210, \":( Bad runtime version\");\n\n bytecode = *((uint16_t **)pc++); // the actual bytecode is here\n\n if (((uint32_t *)bytecode)[0] == 0x923B8E71) {\n variantNotSupported((const char *)bytecode + 16);\n return;\n }\n\n globals = (TValue *)app_alloc(sizeof(TValue) * getNumGlobals());\n memset(globals, 0, sizeof(TValue) * getNumGlobals());\n\n // can be any valid address, best in RAM for speed\n globals[0] = (TValue)&globals;\n\n // just compare the first word\n // TODO\n checkStr(((uint32_t *)bytecode)[0] == 0x923B8E70 && (unsigned)templateHash() == *pc,\n \":( Failed partial flash\");\n\n uintptr_t startptr = (uintptr_t)bytecode;\n\n startptr += 64; // header\n\n initPerfCounters();\n\n initRuntime();\n\n runAction0((Action)startptr);\n\n pxt::releaseFiber();\n}\n\nvoid start() {\n exec_binary((unsigned *)functionsAndBytecode);\n}\n#endif\n\n} // namespace pxt\n\nnamespace Array_ {\n//%\nbool isArray(TValue arr) {\n auto vt = getAnyVTable(arr);\n return vt && vt->classNo == BuiltInType::RefCollection;\n}\n} // namespace Array_\n\nnamespace pxtrt {\n//% expose\nRefCollection *keysOf(TValue v) {\n auto r = NEW_GC(RefCollection);\n MEMDBG(\"mkColl[keys]: => %p\", r);\n if (getAnyVTable(v) != &RefMap_vtable)\n return r;\n auto rm = (RefMap *)v;\n auto len = rm->keys.getLength();\n if (!len)\n return r;\n registerGCObj(r);\n r->setLength(len);\n auto dst = r->getData();\n memcpy(dst, rm->keys.getData(), len * sizeof(TValue));\n unregisterGCObj(r);\n return r;\n}\n//% expose\nTValue mapDeleteByString(RefMap *map, String key) {\n if (getAnyVTable((TValue)map) != &RefMap_vtable)\n soft_panic(PANIC_DELETE_ON_CLASS);\n int i = map->findIdx(key);\n if (i >= 0) {\n map->keys.remove(i);\n map->values.remove(i);\n }\n return TAG_TRUE;\n}\n\n} // namespace pxtrt\n", - "pxt.json": "{\n \"name\": \"base\",\n \"description\": \"The base library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"pxt-core.d.ts\",\n \"pxt.cpp\",\n \"gc.cpp\",\n \"configkeys.h\",\n \"pxtbase.h\",\n \"core.cpp\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"pxt-helpers.ts\",\n \"fixed.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"loops.cpp\",\n \"math.ts\",\n \"ns.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"control.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"poll.ts\",\n \"console.ts\",\n \"json.ts\",\n \"templates.ts\",\n \"eventcontext.ts\",\n \"pause.ts\",\n \"forever.ts\",\n \"utfdecoder.ts\",\n \"scheduling.ts\",\n \"controlmessage.ts\",\n \"perfcounters.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"partial\": true,\n \"yotta\": {\n \"optionalConfig\": {\n \"PXT_GC_CHECKS\": 0\n },\n \"userConfigs\": [\n {\n \"description\": \"(Diagnostics) Garbage Collection checks.\",\n \"config\": {\n \"PXT_GC_CHECKS\": 1\n }\n }\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"base\",\n \"description\": \"The base library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"pxt-core.d.ts\",\n \"pxt.cpp\",\n \"gc.cpp\",\n \"configkeys.h\",\n \"pxtbase.h\",\n \"core.cpp\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"pxt-helpers.ts\",\n \"fixed.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"loops.cpp\",\n \"math.ts\",\n \"ns.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"control.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"poll.ts\",\n \"console.ts\",\n \"json.ts\",\n \"templates.ts\",\n \"eventcontext.ts\",\n \"pause.ts\",\n \"forever.ts\",\n \"utfdecoder.ts\",\n \"scheduling.ts\",\n \"controlmessage.ts\",\n \"perfcounters.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"partial\": true,\n \"yotta\": {\n \"optionalConfig\": {\n \"PXT_GC_CHECKS\": 0\n },\n \"userConfigs\": [\n {\n \"description\": \"(Diagnostics) Garbage Collection checks.\",\n \"config\": {\n \"PXT_GC_CHECKS\": 1\n }\n }\n ]\n }\n}\n", "pxtbase.h": "#ifndef __PXTBASE_H\n#define __PXTBASE_H\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#pragma GCC diagnostic ignored \"-Wformat\"\n#pragma GCC diagnostic ignored \"-Warray-bounds\"\n\n// needed for gcc6; not sure why\n#undef min\n#undef max\n\n#define NOLOG(...) \\\n do { \\\n } while (0)\n\n#define MEMDBG NOLOG\n//#define MEMDBG DMESG\n#define MEMDBG2 NOLOG\n\n#include \"pxtconfig.h\"\n#include \"configkeys.h\"\n\n#ifndef PXT_UTF8\n#define PXT_UTF8 0\n#endif\n\n#if defined(PXT_VM)\n#include \n#if UINTPTR_MAX == 0xffffffff\n#define PXT32 1\n#elif UINTPTR_MAX == 0xffffffffffffffff\n#define PXT64 1\n#else\n#error \"UINTPTR_MAX has invalid value\"\n#endif\n#endif\n\n#define intcheck(...) check(__VA_ARGS__)\n//#define intcheck(...) do {} while (0)\n\n#ifdef PXT_USE_FLOAT\n#define NUMBER float\n#else\n#define NUMBER double\n#endif\n\n#include \n#include \n#include \n\n#ifdef POKY\nvoid *operator new(size_t size, void *ptr);\nvoid *operator new(size_t size);\n#else\n#include \n#endif\n\n#include \"platform.h\"\n#include \"pxtcore.h\"\n\n#ifndef PXT_REGISTER_RESET\n#define PXT_REGISTER_RESET(fn) ((void)0)\n#endif\n\n#define PXT_REFCNT_FLASH 0xfffe\n\n#define CONCAT_1(a, b) a##b\n#define CONCAT_0(a, b) CONCAT_1(a, b)\n// already provided in some platforms, like mbedos\n#ifndef STATIC_ASSERT\n#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) };\n#endif\n\n#ifndef ramint_t\n// this type limits size of arrays\n#if defined(__linux__) || defined(PXT_VM)\n// TODO fix the inline array accesses to take note of this!\n#define ramint_t uint32_t\n#else\n#define ramint_t uint16_t\n#endif\n#endif\n\n#ifndef PXT_IN_ISR\n#define PXT_IN_ISR() (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)\n#endif\n\n#ifdef POKY\ninline void *operator new(size_t, void *p) {\n return p;\n}\ninline void *operator new[](size_t, void *p) {\n return p;\n}\n#endif\n\nnamespace pxt {\n\ntemplate inline const T &max(const T &a, const T &b) {\n if (a < b)\n return b;\n return a;\n}\n\ntemplate inline const T &min(const T &a, const T &b) {\n if (a < b)\n return a;\n return b;\n}\n\ntemplate inline void swap(T &a, T &b) {\n T tmp = a;\n a = b;\n b = tmp;\n}\n\n//\n// Tagged values (assume 4 bytes for now, Cortex-M0)\n//\nstruct TValueStruct {};\ntypedef TValueStruct *TValue;\n\ntypedef TValue TNumber;\ntypedef TValue Action;\ntypedef TValue ImageLiteral;\n\n// To be implemented by the target\nextern \"C\" void target_panic(int error_code);\nextern \"C\" void target_reset();\nvoid sleep_ms(unsigned ms);\nvoid sleep_us(uint64_t us);\nvoid releaseFiber();\nuint64_t current_time_us();\nint current_time_ms();\nvoid initRuntime();\nvoid initSystemTimer();\nvoid sendSerial(const char *data, int len);\nvoid setSendToUART(void (*f)(const char *, int));\nuint64_t getLongSerialNumber();\nvoid registerWithDal(int id, int event, Action a, int flags = 16); // EVENT_LISTENER_DEFAULT_FLAGS\nvoid runInParallel(Action a);\nvoid runForever(Action a);\nvoid waitForEvent(int id, int event);\n//%\nunsigned afterProgramPage();\n//%\nvoid dumpDmesg();\nuint32_t hash_fnv1(const void *data, unsigned len);\n\n// also defined DMESG macro\n// end\n\n#define TAGGED_SPECIAL(n) (TValue)(void *)((n << 2) | 2)\n#define TAG_FALSE TAGGED_SPECIAL(2) // 10\n#define TAG_TRUE TAGGED_SPECIAL(16) // 66\n#define TAG_UNDEFINED (TValue)0\n#define TAG_NULL TAGGED_SPECIAL(1) // 6\n#define TAG_NAN TAGGED_SPECIAL(3) // 14\n#define TAG_NUMBER(n) (TNumber)(void *)(((uintptr_t)(uint32_t)(n) << 1) | 1)\n#define TAG_NON_VALUE TAGGED_SPECIAL(4) // 18; doesn't represent any JS value\n\n#ifdef PXT_VM\ninline bool isEncodedDouble(uint64_t v) {\n return (v >> 48) != 0;\n}\n#endif\n\ninline bool isDouble(TValue v) {\n#ifdef PXT64\n return ((uintptr_t)v >> 48) != 0;\n#else\n (void)v;\n return false;\n#endif\n}\n\ninline bool isPointer(TValue v) {\n return !isDouble(v) && v != 0 && ((intptr_t)v & 3) == 0;\n}\n\ninline bool isTagged(TValue v) {\n return (!isDouble(v) && ((intptr_t)v & 3)) || !v;\n}\n\ninline bool isInt(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 1);\n}\n\ninline bool isSpecial(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 2);\n}\n\ninline bool bothNumbers(TValue a, TValue b) {\n return !isDouble(a) && !isDouble(b) && ((intptr_t)a & (intptr_t)b & 1);\n}\n\ninline int numValue(TValue n) {\n return (int)((intptr_t)n >> 1);\n}\n\ninline bool canBeTagged(int v) {\n (void)v;\n#ifdef PXT_BOX_DEBUG\n return false;\n#elif defined(PXT64)\n return true;\n#else\n return (v << 1) >> 1 == v;\n#endif\n}\n\n// see https://anniecherkaev.com/the-secret-life-of-nan\n\n#define NanBoxingOffset 0x1000000000000LL\n\ntemplate TO bitwise_cast(FROM in) {\n STATIC_ASSERT(sizeof(TO) == sizeof(FROM));\n union {\n FROM from;\n TO to;\n } u;\n u.from = in;\n return u.to;\n}\n\ninline double decodeDouble(uint64_t v) {\n return bitwise_cast(v - NanBoxingOffset);\n}\n\n#ifdef PXT64\nSTATIC_ASSERT(sizeof(void *) == 8);\ninline double doubleVal(TValue v) {\n return bitwise_cast((uint64_t)v - NanBoxingOffset);\n}\n\ninline TValue tvalueFromDouble(double d) {\n return (TValue)(bitwise_cast(d) + NanBoxingOffset);\n}\n#else\nSTATIC_ASSERT(sizeof(void *) == 4);\n#endif\n\n// keep in sym with sim/control.ts\ntypedef enum {\n PANIC_CODAL_OOM = 20,\n PANIC_GC_OOM = 21,\n PANIC_GC_TOO_BIG_ALLOCATION = 22,\n PANIC_CODAL_HEAP_ERROR = 30,\n PANIC_CODAL_NULL_DEREFERENCE = 40,\n PANIC_CODAL_USB_ERROR = 50,\n PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n PANIC_INVALID_BINARY_HEADER = 901,\n PANIC_OUT_OF_BOUNDS = 902,\n PANIC_REF_DELETED = 903,\n PANIC_SIZE = 904,\n PANIC_INVALID_VTABLE = 905,\n PANIC_INTERNAL_ERROR = 906,\n PANIC_NO_SUCH_CONFIG = 907,\n PANIC_NO_SUCH_PIN = 908,\n PANIC_INVALID_ARGUMENT = 909,\n PANIC_MEMORY_LIMIT_EXCEEDED = 910,\n PANIC_SCREEN_ERROR = 911,\n PANIC_MISSING_PROPERTY = 912,\n PANIC_INVALID_IMAGE = 913,\n PANIC_CALLED_FROM_ISR = 914,\n PANIC_HEAP_DUMPED = 915,\n PANIC_STACK_OVERFLOW = 916,\n PANIC_BLOCKING_TO_STRING = 917,\n PANIC_VM_ERROR = 918,\n PANIC_SETTINGS_CLEARED = 920,\n PANIC_SETTINGS_OVERLOAD = 921,\n PANIC_SETTINGS_SECRET_MISSING = 922,\n PANIC_DELETE_ON_CLASS = 923,\n PANIC_OUT_OF_TIMERS = 924,\n PANIC_JACDAC = 925,\n PANIC_MICROPHONE_MISSING = 926,\n PANIC_VARIANT_NOT_SUPPORTED = 927,\n\n PANIC_CAST_FIRST = 980,\n PANIC_CAST_FROM_UNDEFINED = 980,\n PANIC_CAST_FROM_BOOLEAN = 981,\n PANIC_CAST_FROM_NUMBER = 982,\n PANIC_CAST_FROM_STRING = 983,\n PANIC_CAST_FROM_OBJECT = 984,\n PANIC_CAST_FROM_FUNCTION = 985,\n PANIC_CAST_FROM_NULL = 989,\n\n PANIC_UNHANDLED_EXCEPTION = 999,\n\n} PXT_PANIC;\n\nextern const uintptr_t functionsAndBytecode[];\nextern TValue *globals;\nextern uint16_t *bytecode;\nclass RefRecord;\n\n// Utility functions\n\ntypedef TValue (*RunActionType)(Action a, TValue arg0, TValue arg1, TValue arg2);\n\n#define asmRunAction3 ((RunActionType)(((uintptr_t *)bytecode)[12]))\n\nstatic inline TValue runAction3(Action a, TValue arg0, TValue arg1, TValue arg2) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction2(Action a, TValue arg0, TValue arg1) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction1(Action a, TValue arg0) {\n return asmRunAction3(a, arg0, 0, 0);\n}\nstatic inline TValue runAction0(Action a) {\n return asmRunAction3(a, 0, 0, 0);\n}\n\nclass RefAction;\nclass BoxedString;\nstruct VTable;\n\n//%\nAction mkAction(int totallen, RefAction *act);\n//% expose\nint templateHash();\n//% expose\nint programHash();\n//% expose\nBoxedString *programName();\n//% expose\nunsigned programSize();\n//%\nint getNumGlobals();\n//%\nRefRecord *mkClassInstance(VTable *vt);\n//%\nvoid debugMemLeaks();\n//%\nvoid anyPrint(TValue v);\n\n//%\nint getConfig(int key, int defl = -1);\n\n//%\nint toInt(TNumber v);\n//%\nunsigned toUInt(TNumber v);\n//%\nNUMBER toDouble(TNumber v);\n//%\nfloat toFloat(TNumber v);\n//%\nTNumber fromDouble(NUMBER r);\n//%\nTNumber fromFloat(float r);\n\n//%\nTNumber fromInt(int v);\n//%\nTNumber fromUInt(unsigned v);\n//%\nTValue fromBool(bool v);\n//%\nbool eq_bool(TValue a, TValue b);\n//%\nbool eqq_bool(TValue a, TValue b);\n\n//%\nvoid failedCast(TValue v, void *addr = NULL);\n//%\nvoid missingProperty(TValue v);\n\nvoid error(PXT_PANIC code, int subcode = 0);\nvoid exec_binary(unsigned *pc);\nvoid start();\n\nstruct HandlerBinding {\n HandlerBinding *next;\n int source;\n int value;\n Action action;\n#ifndef PXT_CODAL\n uint32_t flags;\n struct Event *pending;\n#endif\n};\nHandlerBinding *findBinding(int source, int value);\nHandlerBinding *nextBinding(HandlerBinding *curr, int source, int value);\nvoid setBinding(int source, int value, Action act);\n\n// Legacy stuff; should no longer be used\n//%\nTValue incr(TValue e);\n//%\nvoid decr(TValue e);\n\ninline TValue incr(TValue e) {\n return e;\n}\ninline void decr(TValue e) {}\n\nclass RefObject;\n\nstatic inline RefObject *incrRC(RefObject *r) {\n return r;\n}\nstatic inline void decrRC(RefObject *) {}\n\ninline void *ptrOfLiteral(int offset) {\n return &bytecode[offset];\n}\n\n// Checks if object is ref-counted, and has a custom PXT vtable in front\n// TODO\ninline bool isRefCounted(TValue e) {\n return isPointer(e);\n}\n\ninline void check(int cond, PXT_PANIC code, int subcode = 0) {\n if (!cond)\n error(code, subcode);\n}\n\ninline void oops(int subcode = 0) {\n target_panic(800 + subcode);\n}\n\nclass RefObject;\n\ntypedef void (*RefObjectMethod)(RefObject *self);\ntypedef unsigned (*RefObjectSizeMethod)(RefObject *self);\ntypedef void *PVoid;\ntypedef void **PPVoid;\n\ntypedef void *Object_;\n\n#define VTABLE_MAGIC 0xF9\n#define VTABLE_MAGIC2 0xF8\n\nenum class ValType : uint8_t {\n Undefined,\n Boolean,\n Number,\n String,\n Object,\n Function,\n};\n\n// keep in sync with pxt-core (search for the type name)\nenum class BuiltInType : uint16_t {\n BoxedString = 1,\n BoxedNumber = 2,\n BoxedBuffer = 3,\n RefAction = 4,\n RefImage = 5,\n RefCollection = 6,\n RefRefLocal = 7,\n RefMap = 8,\n RefMImage = 9, // microbit-specific\n MMap = 10, // linux, mostly ev3\n BoxedString_SkipList = 11, // used by VM bytecode representation only\n BoxedString_ASCII = 12, // ditto\n ZPin = 13,\n User0 = 16,\n};\n\nstruct VTable {\n uint16_t numbytes;\n ValType objectType;\n uint8_t magic;\n#ifdef PXT_VM\n uint16_t ifaceHashEntries;\n BuiltInType lastClassNo;\n#else\n PVoid *ifaceTable;\n#endif\n BuiltInType classNo;\n uint16_t reserved;\n uint32_t ifaceHashMult;\n\n // we only use the first few methods here; pxt will generate more\n PVoid methods[8];\n};\n\n//%\nextern const VTable string_inline_ascii_vt;\n#if PXT_UTF8\n//%\nextern const VTable string_inline_utf8_vt;\n//%\nextern const VTable string_cons_vt;\n//%\nextern const VTable string_skiplist16_vt;\n//%\nextern const VTable string_skiplist16_packed_vt;\n#endif\n//%\nextern const VTable buffer_vt;\n//%\nextern const VTable number_vt;\n//%\nextern const VTable RefAction_vtable;\n\n#ifndef PXT_IS_READONLY\n// assume ARM - ram addresses are 0x2000_0000+; flash is either 0x0+ or 0x0800_0000+\n#define PXT_IS_READONLY(v) (isTagged(v) || !((uintptr_t)v >> 28))\n#endif\n\ninline bool isReadOnly(TValue v) {\n return PXT_IS_READONLY(v);\n}\n\n// A base abstract class for ref-counted objects.\nclass RefObject {\n public:\n const VTable *vtable;\n\n RefObject(const VTable *vt) {\n#if defined(PXT32) && defined(PXT_VM) && !defined(PXT_ESP32)\n if ((uint32_t)vt & 0xf0000000)\n target_panic(PANIC_INVALID_VTABLE);\n#endif\n vtable = vt;\n }\n\n void destroyVT();\n void printVT();\n\n inline uintptr_t vt() { return (uintptr_t)vtable; }\n inline void setVT(uintptr_t v) { vtable = (const VTable *)v; }\n\n inline void ref() {}\n inline void unref() {}\n inline bool isReadOnly() { return pxt::isReadOnly((TValue)this); }\n};\n\nclass Segment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n // this just gives max value of ramint_t\n void growByMin(ramint_t minSize);\n void ensure(ramint_t newSize);\n\n public:\n static constexpr ramint_t MaxSize = (((1U << (8 * sizeof(ramint_t) - 1)) - 1) << 1) + 1;\n static constexpr TValue DefaultValue = TAG_UNDEFINED; // == NULL\n\n Segment() : data(nullptr), length(0), size(0) {}\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n void set(unsigned i, TValue value);\n\n unsigned getLength() { return length; };\n void setLength(unsigned newLength);\n\n void push(TValue value) { set(length, value); }\n TValue pop();\n\n TValue remove(unsigned i);\n void insert(unsigned i, TValue value);\n\n void destroy();\n\n void print();\n\n TValue *getData() { return data; }\n};\n\n// Low-Level segment using system malloc\nclass LLSegment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n public:\n LLSegment() : data(nullptr), length(0), size(0) {}\n\n void set(unsigned idx, TValue v);\n void push(TValue value) { set(length, value); }\n TValue pop();\n void destroy();\n void setLength(unsigned newLen);\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n unsigned getLength() { return length; };\n TValue *getData() { return data; }\n};\n\n// A ref-counted collection of either primitive or ref-counted objects (String, Image,\n// user-defined record, another collection)\nclass RefCollection : public RefObject {\n public:\n Segment head;\n\n RefCollection();\n\n static void destroy(RefCollection *coll);\n static void scan(RefCollection *coll);\n static unsigned gcsize(RefCollection *coll);\n static void print(RefCollection *coll);\n\n unsigned length() { return head.getLength(); }\n void setLength(unsigned newLength) { head.setLength(newLength); }\n TValue getAt(int i) { return head.get(i); }\n TValue *getData() { return head.getData(); }\n};\n\nclass RefMap : public RefObject {\n public:\n Segment keys;\n Segment values;\n\n RefMap();\n static void destroy(RefMap *map);\n static void scan(RefMap *map);\n static unsigned gcsize(RefMap *coll);\n static void print(RefMap *map);\n int findIdx(BoxedString *key);\n};\n\n// A ref-counted, user-defined JS object.\nclass RefRecord : public RefObject {\n public:\n // The object is allocated, so that there is space at the end for the fields.\n TValue fields[];\n\n RefRecord(VTable *v) : RefObject(v) {}\n\n TValue ld(int idx);\n TValue ldref(int idx);\n void st(int idx, TValue v);\n void stref(int idx, TValue v);\n};\n\nstatic inline VTable *getVTable(RefObject *r) {\n return (VTable *)(r->vt() & ~1);\n}\n\nstatic inline VTable *getAnyVTable(TValue v) {\n if (!isRefCounted(v))\n return NULL;\n auto vt = getVTable((RefObject *)v);\n if (vt->magic == VTABLE_MAGIC)\n return vt;\n return NULL;\n}\n\n// these are needed when constructing vtables for user-defined classes\n//%\nvoid RefRecord_destroy(RefRecord *r);\n//%\nvoid RefRecord_print(RefRecord *r);\n//%\nvoid RefRecord_scan(RefRecord *r);\n//%\nunsigned RefRecord_gcsize(RefRecord *r);\n\ntypedef TValue (*ActionCB)(TValue *captured, TValue arg0, TValue arg1, TValue arg2);\n\n// Ref-counted function pointer.\nclass RefAction : public RefObject {\n public:\n uint16_t len;\n uint16_t numArgs;\n#ifdef PXT_VM\n uint16_t initialLen;\n uint16_t flags;\n uintptr_t func;\n#else\n ActionCB func; // The function pointer\n#endif\n // fields[] contain captured locals\n TValue fields[];\n\n static void destroy(RefAction *act);\n static void scan(RefAction *act);\n static unsigned gcsize(RefAction *coll);\n static void print(RefAction *act);\n\n RefAction();\n\n inline void stCore(int idx, TValue v) {\n // DMESG(\"ST [%d] = %d \", idx, v); this->print();\n intcheck(0 <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 10);\n intcheck(fields[idx] == 0, PANIC_OUT_OF_BOUNDS, 11); // only one assignment permitted\n fields[idx] = v;\n }\n};\n\n// These two are used to represent locals written from inside inline functions\nclass RefRefLocal : public RefObject {\n public:\n TValue v;\n static void destroy(RefRefLocal *l);\n static void scan(RefRefLocal *l);\n static unsigned gcsize(RefRefLocal *l);\n static void print(RefRefLocal *l);\n RefRefLocal();\n};\n\ntypedef int color;\n\n// note: this is hardcoded in PXT (hexfile.ts)\n\nclass BoxedNumber : public RefObject {\n public:\n NUMBER num;\n BoxedNumber() : RefObject(&number_vt) {}\n} __attribute__((packed));\n\nclass BoxedString : public RefObject {\n public:\n union {\n struct {\n uint16_t length; // ==size\n char data[0];\n } ascii;\n#if PXT_UTF8\n struct {\n uint16_t size;\n char data[0];\n } utf8;\n struct {\n BoxedString *left;\n BoxedString *right;\n } cons;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t *list;\n } skip;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t list[0];\n } skip_pack;\n#endif\n };\n\n#if PXT_UTF8\n uintptr_t runMethod(int idx) {\n return ((uintptr_t(*)(BoxedString *))vtable->methods[idx])(this);\n }\n const char *getUTF8Data() { return (const char *)runMethod(4); }\n uint32_t getUTF8Size() { return (uint32_t)runMethod(5); }\n // in characters\n uint32_t getLength() { return (uint32_t)runMethod(6); }\n const char *getUTF8DataAt(uint32_t pos) {\n auto meth = ((const char *(*)(BoxedString *, uint32_t))vtable->methods[7]);\n return meth(this, pos);\n }\n#else\n const char *getUTF8Data() { return ascii.data; }\n uint32_t getUTF8Size() { return ascii.length; }\n uint32_t getLength() { return ascii.length; }\n const char *getUTF8DataAt(uint32_t pos) { return pos < ascii.length ? ascii.data + pos : NULL; }\n#endif\n\n TNumber charCodeAt(int pos);\n\n BoxedString(const VTable *vt) : RefObject(vt) {}\n};\n\n// cross version compatible way of accessing string data\n#ifndef PXT_STRING_DATA\n#define PXT_STRING_DATA(str) str->getUTF8Data()\n#endif\n\n// cross version compatible way of accessing string length\n#ifndef PXT_STRING_DATA_LENGTH\n#define PXT_STRING_DATA_LENGTH(str) str->getUTF8Size()\n#endif\n\nclass BoxedBuffer : public RefObject {\n public:\n // data needs to be word-aligned, so we use 32 bits for length\n int length;\n uint8_t data[0];\n BoxedBuffer() : RefObject(&buffer_vt) {}\n\n static bool isInstance(TValue v);\n};\n\n// cross version compatible way of access data field\n#ifndef PXT_BUFFER_DATA\n#define PXT_BUFFER_DATA(buffer) buffer->data\n#endif\n\n// cross version compatible way of access data length\n#ifndef PXT_BUFFER_LENGTH\n#define PXT_BUFFER_LENGTH(buffer) buffer->length\n#endif\n\n#ifndef PXT_CREATE_BUFFER\n#define PXT_CREATE_BUFFER(data, len) pxt::mkBuffer(data, len)\n#endif\n\n// Legacy format:\n// the first byte of data indicates the format - currently 0xE1 or 0xE4 to 1 or 4 bit bitmaps\n// second byte indicates width in pixels\n// third byte indicates the height (which should also match the size of the buffer)\n// just like ordinary buffers, these can be layed out in flash\n\n// Current format:\n// 87 BB WW WW HH HH 00 00 DATA\n// that is: 0x87, 0x01 or 0x04 - bpp, width in little endian, height, 0x00, 0x00 followed by data\n// for 4 bpp images, rows are word-aligned (as in legacy)\n\n#define IMAGE_HEADER_MAGIC 0x87\n\nstruct ImageHeader {\n uint8_t magic;\n uint8_t bpp;\n uint16_t width;\n uint16_t height;\n uint16_t padding;\n uint8_t pixels[0];\n};\n\nclass RefImage : public RefObject {\n public:\n BoxedBuffer *buffer;\n uint32_t revision;\n\n RefImage(BoxedBuffer *buf);\n RefImage(uint32_t sz);\n\n void setBuffer(BoxedBuffer *b);\n\n uint8_t *data() { return buffer->data; }\n int length() { return (int)buffer->length; }\n\n ImageHeader *header() { return (ImageHeader *)buffer->data; }\n int pixLength() { return length() - sizeof(ImageHeader); }\n\n int width() { return header()->width; }\n int height() { return header()->height; }\n int wordHeight();\n int bpp() { return header()->bpp; }\n\n bool hasPadding() { return (height() & 0x7) != 0; }\n\n uint8_t *pix() { return header()->pixels; }\n\n int byteHeight() {\n if (bpp() == 1)\n return (height() + 7) >> 3;\n else if (bpp() == 4)\n return ((height() * 4 + 31) >> 5) << 2;\n else {\n oops(21);\n return -1;\n }\n }\n\n uint8_t *pix(int x, int y) {\n uint8_t *d = &pix()[byteHeight() * x];\n if (y) {\n if (bpp() == 1)\n d += y >> 3;\n else if (bpp() == 4)\n d += y >> 1;\n }\n return d;\n }\n\n uint8_t fillMask(color c);\n bool inRange(int x, int y);\n void clamp(int *x, int *y);\n void makeWritable();\n\n static void destroy(RefImage *t);\n static void scan(RefImage *t);\n static unsigned gcsize(RefImage *t);\n static void print(RefImage *t);\n};\n\nRefImage *mkImage(int w, int h, int bpp);\n\ntypedef BoxedBuffer *Buffer;\ntypedef BoxedString *String;\ntypedef RefImage *Image_;\n\nuint32_t toRealUTF8(String str, uint8_t *dst);\n\n// keep in sync with github/pxt/pxtsim/libgeneric.ts\nenum class NumberFormat {\n Int8LE = 1,\n UInt8LE,\n Int16LE,\n UInt16LE,\n Int32LE,\n Int8BE,\n UInt8BE,\n Int16BE,\n UInt16BE,\n Int32BE,\n\n UInt32LE,\n UInt32BE,\n Float32LE,\n Float64LE,\n Float32BE,\n Float64BE,\n};\n\n// this will, unlike mkStringCore, UTF8-canonicalize the data\nString mkString(const char *data, int len = -1);\n// data can be NULL in both cases\nBuffer mkBuffer(const void *data, int len);\nString mkStringCore(const char *data, int len = -1);\n\nTNumber getNumberCore(uint8_t *buf, int size, NumberFormat format);\nvoid setNumberCore(uint8_t *buf, int size, NumberFormat format, TNumber value);\n\nvoid seedRandom(unsigned seed);\nvoid seedAddRandom(unsigned seed);\n// max is inclusive\nunsigned getRandom(unsigned max);\n\nValType valType(TValue v);\n\n// this is equivalent to JS `throw v`; it will leave\n// the current function(s), all the way until the nearest try block and\n// ignore all destructors (think longjmp())\nvoid throwValue(TValue v);\n\nvoid registerGC(TValue *root, int numwords = 1);\nvoid unregisterGC(TValue *root, int numwords = 1);\nvoid registerGCPtr(TValue ptr);\nvoid unregisterGCPtr(TValue ptr);\nstatic inline void registerGCObj(RefObject *ptr) {\n registerGCPtr((TValue)ptr);\n}\nstatic inline void unregisterGCObj(RefObject *ptr) {\n unregisterGCPtr((TValue)ptr);\n}\nvoid gc(int flags);\n\nstruct StackSegment {\n void *top;\n void *bottom;\n StackSegment *next;\n};\n\n#define NUM_TRY_FRAME_REGS 3\nstruct TryFrame {\n TryFrame *parent;\n uintptr_t registers[NUM_TRY_FRAME_REGS];\n};\n\nstruct ThreadContext {\n TValue *globals;\n StackSegment stack;\n TryFrame *tryFrame;\n TValue thrownValue;\n#ifdef PXT_GC_THREAD_LIST\n ThreadContext *next;\n ThreadContext *prev;\n#endif\n};\n\n#ifdef PXT_GC_THREAD_LIST\nextern ThreadContext *threadContexts;\nvoid *threadAddressFor(ThreadContext *, void *sp);\n#endif\n\nvoid releaseThreadContext(ThreadContext *ctx);\nThreadContext *getThreadContext();\nvoid setThreadContext(ThreadContext *ctx);\n\n#ifndef PXT_GC_THREAD_LIST\nvoid gcProcessStacks(int flags);\n#endif\n\nvoid gcProcess(TValue v);\nvoid gcFreeze();\n\n#ifdef PXT_VM\nvoid gcStartup();\nvoid gcPreStartup();\n#endif\n\nvoid coreReset();\nvoid gcReset();\nvoid systemReset();\n\nvoid doNothing();\n\nvoid *gcAllocate(int numbytes);\nvoid *gcAllocateArray(int numbytes);\nextern \"C\" void *app_alloc(int numbytes);\nextern \"C\" void *app_free(void *ptr);\nextern \"C\" void *app_alloc_at(void *at, int numbytes);\nvoid gcPreAllocateBlock(uint32_t sz);\n\nint redirectSamples(int16_t *dst, int numsamples, int samplerate);\n\n#ifdef PXT64\n#define TOWORDS(bytes) (((bytes) + 7) >> 3)\n#else\n#define TOWORDS(bytes) (((bytes) + 3) >> 2)\n#endif\n\n#ifndef PXT_VM\n#define soft_panic target_panic\n#endif\n\nextern int debugFlags;\n\nenum class PerfCounters {\n GC,\n};\n\n#ifdef PXT_PROFILE\n#ifndef PERF_NOW\n#error \"missing platform timer support\"\n#endif\n\nstruct PerfCounter {\n uint32_t value;\n uint32_t numstops;\n uint32_t start;\n};\n\nextern struct PerfCounter *perfCounters;\n\nvoid initPerfCounters();\n//%\nvoid dumpPerfCounters();\n//%\nvoid startPerfCounter(PerfCounters n);\n//%\nvoid stopPerfCounter(PerfCounters n);\n#else\ninline void startPerfCounter(PerfCounters n) {}\ninline void stopPerfCounter(PerfCounters n) {}\ninline void initPerfCounters() {}\ninline void dumpPerfCounters() {}\n#endif\n\n// Handling of built-in string literals (like \"[Object]\", \"true\" etc.).\n\n// This has the same layout as BoxedString, but has statically allocated buffer\ntemplate struct BoxedStringLayout {\n const void *vtable;\n uint16_t size;\n const char data[N];\n};\n\ntemplate constexpr size_t _boxedStringLen(char const (&)[N]) {\n return N;\n}\n\n// strings defined here as used as (String)name\n#define PXT_DEF_STRING(name, val) \\\n const BoxedStringLayout<_boxedStringLen(val)> name[1] = { \\\n {&pxt::string_inline_ascii_vt, _boxedStringLen(val) - 1, val}};\n\n// bigger value - less memory, but slower\n// 16/20 keeps s.length and s.charCodeAt(i) at about 200 cycles (for actual unicode strings),\n// which is similar to amortized allocation time\n#define PXT_STRING_SKIP_INCR 16 // needs to be power of 2; needs to be kept in sync with compiler\n#define PXT_STRING_MIN_SKIP \\\n 20 // min. size of string to use skip list; static code has its own limit\n\n#define PXT_NUM_SKIP_ENTRIES(p) ((p)->skip.length / PXT_STRING_SKIP_INCR)\n#define PXT_SKIP_DATA_IND(p) ((const char *)(p->skip.list + PXT_NUM_SKIP_ENTRIES(p)))\n#define PXT_SKIP_DATA_PACK(p) ((const char *)(p->skip_pack.list + PXT_NUM_SKIP_ENTRIES(p)))\n\n} // namespace pxt\n\nusing namespace pxt;\n\nnamespace numops {\n//%\nString toString(TValue v);\n//%\nint toBool(TValue v);\n//%\nint toBoolDecr(TValue v);\n} // namespace numops\n\nnamespace pxt {\ninline bool toBoolQuick(TValue v) {\n if (v == TAG_TRUE)\n return true;\n if (v == TAG_FALSE || v == TAG_UNDEFINED || v == TAG_NULL)\n return false;\n return numops::toBool(v);\n}\n} // namespace pxt\n\nnamespace pxtrt {\n//%\nRefMap *mkMap();\n//%\nTValue mapGetByString(RefMap *map, String key);\n//%\nint lookupMapKey(String key);\n//%\nTValue mapGet(RefMap *map, unsigned key);\n//% expose\nvoid mapSetByString(RefMap *map, String key, TValue val);\n//%\nvoid mapSet(RefMap *map, unsigned key, TValue val);\n} // namespace pxtrt\n\nnamespace pins {\nBuffer createBuffer(int size);\n}\n\nnamespace String_ {\n//%\nint compare(String a, String b);\n} // namespace String_\n\nnamespace Array_ {\n//%\nRefCollection *mk();\n//%\nint length(RefCollection *c);\n//%\nvoid setLength(RefCollection *c, int newLength);\n//%\nvoid push(RefCollection *c, TValue x);\n//%\nTValue pop(RefCollection *c);\n//%\nTValue getAt(RefCollection *c, int x);\n//%\nvoid setAt(RefCollection *c, int x, TValue y);\n//%\nTValue removeAt(RefCollection *c, int x);\n//%\nvoid insertAt(RefCollection *c, int x, TValue value);\n//%\nint indexOf(RefCollection *c, TValue x, int start);\n//%\nbool removeElement(RefCollection *c, TValue x);\n} // namespace Array_\n\n#define NEW_GC(T, ...) new (gcAllocate(sizeof(T))) T(__VA_ARGS__)\n\n// The ARM Thumb generator in the JavaScript code is parsing\n// the hex file and looks for the magic numbers as present here.\n//\n// Then it fetches function pointer addresses from there.\n//\n// The vtable pointers are there, so that the ::emptyData for various types\n// can be patched with the right vtable.\n//\n#define PXT_SHIMS_BEGIN \\\n namespace pxt { \\\n const uintptr_t functionsAndBytecode[] \\\n __attribute__((aligned(0x20))) = {0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,\n\n#define PXT_SHIMS_END \\\n } \\\n ; \\\n }\n\n#if !defined(X86_64) && !defined(PXT_VM)\n#pragma GCC diagnostic ignored \"-Wpmf-conversions\"\n#endif\n\n#ifdef PXT_VM\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#else\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#endif\n\n#define PXT_VTABLE(classname, valtp) \\\n DEF_VTABLE(classname##_vtable, classname, valtp, (void *)&classname::destroy, \\\n (void *)&classname::print, (void *)&classname::scan, (void *)&classname::gcsize)\n\n#define PXT_EXT_VTABLE(classname) \\\n static int classname##_gcsize() { return sizeof(classname); } \\\n DEF_VTABLE_EXT(classname##_vtable, classname, ValType::Object, (void *)&pxt::doNothing, \\\n (void *)&pxt::anyPrint, (void *)&pxt::doNothing, (void *)&classname##_gcsize)\n\n#define PXT_VTABLE_INIT(classname) RefObject(&classname##_vtable)\n\n#define PXT_VTABLE_CTOR(classname) \\\n PXT_VTABLE(classname, ValType::Object) \\\n classname::classname() : PXT_VTABLE_INIT(classname)\n\n#define PXT_MAIN \\\n int main() { \\\n pxt::start(); \\\n return 0; \\\n }\n\n#define PXT_FNPTR(x) (uintptr_t)(void *)(x)\n\n#define PXT_ABI(...)\n\n#define JOIN(a, b) a##b\n/// Defines getClassName() function to fetch the singleton\n#define SINGLETON(ClassName) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n/// Defines getClassName() function to fetch the singleton if PIN present\n#define SINGLETON_IF_PIN(ClassName, pin) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName) && LOOKUP_PIN(pin)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n#ifdef PXT_VM\n#include \"vm.h\"\n#endif\n\n#endif\n", "scheduling.ts": "/**\n * Calls a function with a fixed time delay between each call to that function.\n * @param func \n * @param delay \n */\n//%\nfunction setInterval(func: () => void, delay: number): number {\n delay = Math.max(10, delay | 0);\n return control.setInterval(func, delay, control.IntervalMode.Interval);\n}\n\n/**\n * Cancels repeated action which was set up using setInterval().\n * @param intervalId \n */\n//%\nfunction clearInterval(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Interval);\n}\n\n/**\n * Calls a function after specified delay.\n * @param func \n * @param delay \n */\n//%\nfunction setTimeout(func: () => void, delay: number): number {\n return control.setInterval(func, delay, control.IntervalMode.Timeout);\n}\n\n/**\n * Clears the delay set by setTimeout().\n * @param intervalId \n */\n//%\nfunction clearTimeout(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Timeout);\n}\n\n/**\n * Calls a function as soon as possible.\n * @param func \n */\n//%\nfunction setImmediate(func: () => void): number {\n return control.setInterval(func, 0, control.IntervalMode.Immediate);\n}\n\n/**\n * Cancels the immediate actions.\n * @param intervalId \n */\n//%\nfunction clearImmediate(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Immediate);\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\ndeclare interface Buffer {\n /**\n * Reads an unsigned byte at a particular location\n */\n //% shim=BufferMethods::getUint8\n getUint8(off: int32): int32;\n\n /**\n * Returns false when the buffer can be written to.\n */\n //% shim=BufferMethods::isReadOnly\n isReadOnly(): boolean;\n\n /**\n * Writes an unsigned byte at a particular location\n */\n //% shim=BufferMethods::setUint8\n setUint8(off: int32, v: int32): void;\n\n /**\n * Write a number in specified format in the buffer.\n */\n //% shim=BufferMethods::setNumber\n setNumber(format: NumberFormat, offset: int32, value: number): void;\n\n /**\n * Read a number in specified format from the buffer.\n */\n //% shim=BufferMethods::getNumber\n getNumber(format: NumberFormat, offset: int32): number;\n\n /** Returns the length of a Buffer object. */\n //% property shim=BufferMethods::length\n length: int32;\n\n /**\n * Fill (a fragment) of the buffer with given value.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::fill\n fill(value: int32, offset?: int32, length?: int32): void;\n\n /**\n * Return a copy of a fragment of a buffer.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::slice\n slice(offset?: int32, length?: int32): Buffer;\n\n /**\n * Shift buffer left in place, with zero padding.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus\n * start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::shift\n shift(offset: int32, start?: int32, length?: int32): void;\n\n /**\n * Convert a buffer to string assuming UTF8 encoding\n */\n //% shim=BufferMethods::toString\n toString(): string;\n\n /**\n * Convert a buffer to its hexadecimal representation.\n */\n //% shim=BufferMethods::toHex\n toHex(): string;\n\n /**\n * Rotate buffer left in place.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus\n * start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::rotate\n rotate(offset: int32, start?: int32, length?: int32): void;\n\n /**\n * Write contents of `src` at `dstOffset` in current buffer.\n */\n //% shim=BufferMethods::write\n write(dstOffset: int32, src: Buffer): void;\n\n /**\n * Compute k-bit FNV-1 non-cryptographic hash of the buffer.\n */\n //% shim=BufferMethods::hash\n hash(bits: int32): uint32;\n}\ndeclare namespace control {\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% deprecated=1 shim=control::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Create a new buffer with UTF8-encoded string\n * @param str the string to put in the buffer\n */\n //% deprecated=1 shim=control::createBufferFromUTF8\n function createBufferFromUTF8(str: string): Buffer;\n}\ndeclare namespace loops {\n\n /**\n * Repeats the code forever in the background. On each iteration, allows other codes to run.\n * @param body code to execute\n */\n //% help=loops/forever weight=100 afterOnStart=true deprecated=true\n //% blockId=forever_deprecated block=\"forever\" blockAllowMultiple=1 shim=loops::forever\n function forever(a: () => void): void;\n\n /**\n * Pause for the specified time in milliseconds\n * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000\n */\n //% help=loops/pause weight=99 deprecated=true\n //% async block=\"pause %pause=timePicker|ms\"\n //% blockId=device_pause_deprecated shim=loops::pause\n function pause(ms: int32): void;\n}\ndeclare namespace control {\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=control/millis weight=50\n //% blockId=control_running_time block=\"millis (ms)\" shim=control::millis\n function millis(): int32;\n\n /**\n * Gets current time in microseconds. Overflows every ~18 minutes.\n */\n //% shim=control::micros\n function micros(): int32;\n\n /**\n * Used internally\n */\n //% flags.defl=16 shim=control::internalOnEvent\n function internalOnEvent(src: int32, value: int32, handler: () => void, flags?: int32): void;\n\n /**\n * Reset the device.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\" shim=control::reset\n function reset(): void;\n\n /**\n * Block the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29 async\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\" shim=control::waitMicros\n function waitMicros(micros: int32): void;\n\n /**\n * Run other code in the parallel.\n */\n //% help=control/run-in-parallel handlerStatement=1\n //% blockId=\"control_run_in_parallel\" block=\"run in parallel\" blockGap=8 shim=control::runInParallel\n function runInParallel(a: () => void): void;\n\n /**\n * Blocks the calling thread until the specified event is raised.\n */\n //% help=control/wait-for-event async\n //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\" shim=control::waitForEvent\n function waitForEvent(src: int32, value: int32): void;\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9\n //% help=control/device-serial-number shim=control::deviceSerialNumber\n function deviceSerialNumber(): int32;\n\n /**\n * Derive a unique, consistent 64-bit serial number of this device from internal data.\n */\n //% blockId=\"control_device_long_serial_number\" block=\"device long serial number\" weight=9\n //% help=control/device-long-serial-number shim=control::deviceLongSerialNumber\n function deviceLongSerialNumber(): Buffer;\n\n /**\n *\n */\n //% shim=control::__log\n function __log(prority: int32, text: string): void;\n\n /**\n * Dump internal information about a value.\n */\n //% shim=control::dmesgValue\n function dmesgValue(v: any): void;\n}\ndeclare namespace control {\n\n /**\n * Force GC and dump basic information about heap.\n */\n //% shim=control::gc\n function gc(): void;\n\n /**\n * Force GC and halt waiting for debugger to do a full heap dump.\n */\n //% shim=control::heapDump\n function heapDump(): void;\n\n /**\n * Set flags used when connecting an external debugger.\n */\n //% shim=control::setDebugFlags\n function setDebugFlags(flags: int32): void;\n\n /**\n * Record a heap snapshot to debug memory leaks.\n */\n //% shim=control::heapSnapshot\n function heapSnapshot(): void;\n\n /**\n * Return true if profiling is enabled in the current build.\n */\n //% shim=control::profilingEnabled\n function profilingEnabled(): boolean;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -689,7 +690,7 @@ var pxtTargetBundle = { "platform.cpp": "#include \"pxt.h\"\n#include \"light.h\"\n\nnamespace pxt {\n\nCODAL_TIMER devTimer;\n\nstatic void initRandomSeed() {\n int seed = 0xC0DA1;\n auto pinTemp = LOOKUP_PIN(TEMPERATURE);\n if (pinTemp)\n seed *= pinTemp->getAnalogValue();\n auto pinLight = LOOKUP_PIN(LIGHT);\n if (pinLight)\n seed *= pinLight->getAnalogValue();\n seedRandom(seed);\n}\n\nstatic void remapSwdPin(int pinCfg, int fallback) {\n int pinName = getConfig(pinCfg);\n if (pinName == PA30 || pinName == PA31) {\n if (getConfig(CFG_SWD_ENABLED, 0)) {\n linkPin(pinName, fallback);\n } else {\n PORT->Group[pinName / 32].PINCFG[pinName % 32].reg = (uint8_t)PORT_PINCFG_INEN;\n }\n }\n}\n\nstatic void initSwdPins() {\n remapSwdPin(CFG_PIN_NEOPIXEL, PIN(D0));\n remapSwdPin(CFG_PIN_RXLED, PIN(D1));\n remapSwdPin(CFG_PIN_SPEAKER_AMP, PIN(D2));\n}\n\nvoid platform_init() {\n initSwdPins();\n initRandomSeed();\n light::clear();\n\n if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n *HF2_DBG_MAGIC_PTR = 0;\n // this will cause alignment fault at the first breakpoint\n globals[0] = (TValue)1;\n }\n}\n\n} // namespace pxt\n", "platform.h": "#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n// This is specific for SAMD21, to be replaced in other Codal targets.\n\n#include \"CapTouchButton.h\"\n#include \"Image.h\"\n#include \"MbedTimer.h\"\n#include \"MbedI2C.h\"\n#include \"MbedPin.h\"\n#include \"MbedSPI.h\"\n#include \"MbedSerial.h\"\n#include \"MultiButton.h\"\n#include \"CPlayI2C.h\"\n\n#include \"SAMD21DMAC.h\"\n\n// Analog Pins, all SAMD21: PA02-PA11 PB00-PB09 (some pins not connected)\n// 2 ports times 32 pins in each\n#define DEV_NUM_PINS 64\n// pins marked with AIN and PTC in the data sheet\n#define DEV_ANALOG_PINS 0x3ff00000ffcULL\n\n#define PAGE_SIZE 256\n\n#define CODAL_DMAC SAMD21DMAC\n\n// this is codal::_mbed for both mbed and mbedos now\n#define CODAL_MBED codal::_mbed\n\n#define CODAL_I2C codal::CPlayI2C\n\n#ifndef IMAGE_BITS\n#define IMAGE_BITS 1\n#endif\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n#define PA00 0\n#define PA01 1\n#define PA02 2\n#define PA03 3\n#define PA04 4\n#define PA05 5\n#define PA06 6\n#define PA07 7\n#define PA08 8\n#define PA09 9\n#define PA10 10\n#define PA11 11\n#define PA12 12\n#define PA13 13\n#define PA14 14\n#define PA15 15\n#define PA16 16\n#define PA17 17\n#define PA18 18\n#define PA19 19\n#define PA20 20\n#define PA21 21\n#define PA22 22\n#define PA23 23\n#define PA24 24\n#define PA25 25\n#define PA26 26\n#define PA27 27\n#define PA28 28\n#define PA29 29\n#define PA30 30\n#define PA31 31\n#define PB00 32\n#define PB01 33\n#define PB02 34\n#define PB03 35\n#define PB04 36\n#define PB05 37\n#define PB06 38\n#define PB07 39\n#define PB08 40\n#define PB09 41\n#define PB10 42\n#define PB11 43\n#define PB12 44\n#define PB13 45\n#define PB14 46\n#define PB15 47\n#define PB16 48\n#define PB17 49\n#define PB18 50\n#define PB19 51\n#define PB20 52\n#define PB21 53\n#define PB22 54\n#define PB23 55\n#define PB24 56\n#define PB25 57\n#define PB26 58\n#define PB27 59\n#define PB28 60\n#define PB29 61\n#define PB30 62\n#define PB31 63\n#endif\n\n#endif\n", "pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n", - "pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", "pxtcore.h": "#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n", "pxtparts.json": "{\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 19,\n \"y\": 0\n },\n {\n \"x\": 28,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"dotstar\": {\n \"simulationBehavior\": \"dotstar\",\n \"visual\": {\n \"builtIn\": \"dotstar\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 1\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createAPA102Strip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"dataPin\"\n },\n {\n \"pinInstantiationIdx\": 1,\n \"partParameter\": \"clkPin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n },\n \"pixels\": {\n \"simulationBehavior\": \"pixels\",\n \"visual\": { \n \"builtIn\": \"pixels\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"MOSI\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCK\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n }, \n \"buttons\": {\n \"simulationBehavior\": \"buttons\",\n \"visual\": {\n \"builtIn\": \"buttons\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 45\n }\n ]\n },\n \"numberOfPins\": 2,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"button\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"slideswitch\": {\n \"numberOfPins\": 3,\n \"simulationBehavior\": \"slideswitch\",\n \"visual\": {\n \"builtIn\": \"slideswitch\",\n \"width\": 100,\n \"height\": 100,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 0\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 5\n },\n {\n \"x\": 37,\n \"y\": 5\n },\n {\n \"x\": 45,\n \"y\": 5\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"led\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"analogled\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"photocell\": {\n \"numberOfPins\": 3,\n \"visual\": {\n \"builtIn\": \"photocell\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 15,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"photocell\",\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n }\n}", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace light {\n\n /**\n * Send a programmable light buffer to the specified digital pin\n * @param data The pin that the lights are connected to\n * @param clk the clock line if any\n * @param mode the color encoding mode\n * @param buf The buffer to send to the pin\n */\n //% shim=light::sendBuffer\n function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n /**\n * Determines if the USB has been enumerated.\n */\n //% shim=control::isUSBInitialized\n function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n /**\n * Get a pin by configuration id (DAL.CFG_PIN...)\n */\n //% shim=pins::pinByCfg\n function pinByCfg(key: int32): DigitalInOutPin;\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=pins::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration blockGap=8\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=19 shim=pins::pulseDuration\n function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read weight=53\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n //% blockNamespace=pins\n //% parts=\"photocell\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=AnalogInPinMethods::analogRead\n analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write weight=52\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n //% blockNamespace=pins\n //%parts=\"analogled\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.min=0 value.max=1023\n //% trackArgs=0 shim=AnalogOutPinMethods::analogWrite\n analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read weight=61\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalRead\n digitalRead(): boolean;\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin\n */\n //% help=pins/digital-write weight=60\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n //% parts=\"led\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalWrite\n digitalWrite(value: boolean): void;\n\n /**\n * Make this pin a digital input, and create events where the timestamp is the duration\n * that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=16 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n onPulsed(pulse: PulseValue, body: () => void): void;\n\n /**\n * Register code to run when a pin event occurs.\n */\n //% help=pins/on-event weight=20 blockGap=8\n //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::onEvent\n onEvent(event: PinEvent, body: () => void): void;\n\n /**\n * Return the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %high||timeout %maxDuration (µs)\"\n //% weight=18 blockGap=8\n //% help=\"pins/pulse-in\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n /**\n * Set the pull direction of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone\n */\n //% help=pins/set-pull weight=17 blockGap=8\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n /**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=51\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n analogSetPeriod(period: int32): void;\n\n /**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed\n */\n //% help=pins/servo-write weight=41 group=\"Servo\"\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n //% parts=microservo trackArgs=0\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n servoWrite(value?: int32): void;\n\n /**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n //% parts=microservo blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n servoSetPulse(duration: int32): void;\n\n /**\n * Indicates if the servo is running continuously\n */\n //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n /**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n //% help=control/raise-event\n //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n function raiseEvent(src: int32, value: int32): void;\n\n /**\n * Determine the version of system software currently running.\n */\n //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n //% help=control/device-dal-version shim=control::deviceDalVersion\n function deviceDalVersion(): string;\n\n /**\n * Allocates the next user notification event\n */\n //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n function allocateNotifyEvent(): int32;\n\n /** Write a message to DMESG debugging buffer. */\n //% shim=control::dmesg\n function dmesg(s: string): void;\n\n /** Write a message and value (pointer) to DMESG debugging buffer. */\n //% shim=control::dmesgPtr\n function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::readBuffer\n readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::writeBuffer\n writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n /**\n * Opens a Serial communication driver\n */\n //% help=pins/create-i2c\n //% parts=i2c shim=pins::createI2C\n function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n /**\n * Opens a SPI driver\n */\n //% help=pins/create-spi\n //% parts=spi shim=pins::createSPI\n function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n /**\n * Opens a slave SPI driver\n */\n //% parts=spi shim=pins::createSlaveSPI\n function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n /**\n * Write to the SPI bus\n */\n //% shim=SPIMethods::write\n write(value: int32): int32;\n\n /**\n * Transfer buffers over the SPI bus\n */\n //% argsNullable shim=SPIMethods::transfer\n transfer(command: Buffer, response: Buffer): void;\n\n /**\n * Sets the SPI clock frequency\n */\n //% shim=SPIMethods::setFrequency\n setFrequency(frequency: int32): void;\n\n /**\n * Sets the SPI bus mode\n */\n //% shim=SPIMethods::setMode\n setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n /**\n * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n * @param value the data (max 32 characters)\n */\n //% shim=configStorage::setBuffer\n function setBuffer(key: string, value: Buffer): void;\n\n /**\n * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::getBuffer\n function getBuffer(key: string): Buffer;\n\n /**\n * Removes the key from local storage\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::removeItem\n function removeItem(key: string): void;\n\n /**\n * Clears the local storage\n */\n //% shim=configStorage::clear\n function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -730,7 +731,7 @@ var pxtTargetBundle = { "platform.cpp": "#include \"pxt.h\"\n#include \"STM32LowLevelTimer.h\"\n#include \"Accelerometer.h\"\n\nnamespace pxt {\n\nstruct TimerConfig {\n uint8_t id;\n uint8_t irqn;\n TIM_TypeDef *addr;\n};\n\n#define DEF_TIM(n) \\\n { 0x10 + n, TIM##n##_IRQn, TIM##n }\n\nstatic const TimerConfig timers[] = {\n#ifdef TIM1\n DEF_TIM(1),\n#endif\n#ifdef TIM2\n DEF_TIM(2),\n#endif\n#ifdef TIM3\n DEF_TIM(3),\n#endif\n#ifdef TIM4\n DEF_TIM(4),\n#endif\n#ifdef TIM5\n DEF_TIM(5),\n#endif\n#ifdef TIM6\n DEF_TIM(6),\n#endif\n#ifdef TIM7\n DEF_TIM(7),\n#endif\n#ifdef TIM8\n DEF_TIM(8),\n#endif\n#ifdef TIM9\n DEF_TIM(9),\n#endif\n#ifdef TIM10\n DEF_TIM(10),\n#endif\n#ifdef TIM11\n DEF_TIM(11),\n#endif\n#ifdef TIM12\n DEF_TIM(12),\n#endif\n#ifdef TIM13\n DEF_TIM(13),\n#endif\n#ifdef TIM14\n DEF_TIM(14),\n#endif\n#ifdef TIM15\n DEF_TIM(15),\n#endif\n {0, 0, 0}};\n\n#ifdef STM32F1\n#define DEF_TIMERS 0x14120000 // TIM4 TIM2\n#else\n#define DEF_TIMERS 0x15120000 // TIM5 TIM2\n#endif\n\nstatic uint32_t usedTimers;\nstatic int timerIdx(uint8_t id) {\n for (unsigned i = 0; timers[i].id; i++) {\n if (id == timers[i].id)\n return i;\n }\n return -1;\n}\nLowLevelTimer *allocateTimer() {\n uint32_t timersToUse = getConfig(CFG_TIMERS_TO_USE, DEF_TIMERS);\n for (int shift = 24; shift >= 0; shift -= 8) {\n uint8_t tcId = (timersToUse >> shift) & 0xff;\n int idx = timerIdx(tcId);\n if (idx < 0 || (usedTimers & (1 << idx)))\n continue;\n auto dev = timers[idx].addr;\n if (dev->CR1 & TIM_CR1_CEN)\n continue;\n usedTimers |= 1 << idx;\n DMESG(\"allocate TIM%d\", tcId - 0x10);\n return new STM32LowLevelTimer(dev, (IRQn_Type)timers[idx].irqn);\n }\n\n target_panic(PANIC_OUT_OF_TIMERS);\n return NULL;\n}\n\nvoid initAccelRandom();\n#ifdef STM32F4\nextern \"C\" void apply_clock_init(RCC_OscInitTypeDef *oscInit, RCC_ClkInitTypeDef *clkConfig, uint32_t flashLatency) {\n\n int mhz = getConfig(CFG_CPU_MHZ, 84);\n\n if (mhz >= 216) {\n oscInit->PLL.PLLN = 432;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 9;\n flashLatency = FLASH_LATENCY_6;\n } else if (mhz >= 192) {\n oscInit->PLL.PLLN = 384;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 8;\n flashLatency = FLASH_LATENCY_6;\n } else if (mhz >= 168) {\n oscInit->PLL.PLLN = 336;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 7;\n flashLatency = FLASH_LATENCY_5;\n } else if (mhz >= 144) {\n oscInit->PLL.PLLN = 288;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 6;\n flashLatency = FLASH_LATENCY_5;\n } else if (mhz >= 108) {\n oscInit->PLL.PLLN = 432;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 9;\n flashLatency = FLASH_LATENCY_4;\n } else if (mhz >= 96) {\n oscInit->PLL.PLLN = 384;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 8;\n flashLatency = FLASH_LATENCY_3;\n } else if (mhz >= 84) {\n // this is the default from codal\n oscInit->PLL.PLLN = 336;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 7;\n flashLatency = FLASH_LATENCY_2;\n } else {\n target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n }\n\n DMESG(\"CPU clock: %dMHz -> %dMHz\", mhz, oscInit->PLL.PLLN / (oscInit->PLL.PLLP == RCC_PLLP_DIV4 ? 4 : 2));\n\n if (mhz > 108) {\n clkConfig->APB1CLKDivider = RCC_HCLK_DIV4;\n clkConfig->APB2CLKDivider = RCC_HCLK_DIV2;\n } else {\n clkConfig->APB1CLKDivider = RCC_HCLK_DIV2;\n clkConfig->APB2CLKDivider = RCC_HCLK_DIV1;\n }\n\n HAL_RCC_OscConfig(oscInit);\n HAL_RCC_ClockConfig(clkConfig, flashLatency);\n}\n#endif\n\n// Disable seeding random from accelerometer. We now store random\n// seed in internal flash, so it's different on every reset, and\n// accelerometer sometimes have bugs, so better not enable them unless\n// requested.\nstatic void initRandomSeed() {\n#if 0\n if (getConfig(CFG_ACCELEROMETER_TYPE, -1) != -1) {\n initAccelRandom();\n }\n#endif\n}\n\nstatic void set_if_present(int cfg, int val) {\n auto snd = pxt::lookupPinCfg(cfg);\n if (snd)\n snd->setDigitalValue(val);\n}\n\n//%\nvoid deepSleep() {\n // this in particular puts accelerometer to sleep, which the bootloader\n // doesn't do\n CodalComponent::setAllSleep(true);\n\n#ifdef STM32F4\n // ask bootloader to do the deep sleeping\n QUICK_BOOT(1);\n RTC->BKP1R = 0x10b37889;\n NVIC_SystemReset();\n#endif\n}\n\nvoid platformSendSerial(const char *data, int len) {\n /*\n if (!serial) {\n serial = new codal::_mbed::Serial(USBTX, NC);\n serial->baud(9600);\n }\n serial->send((uint8_t*)data, len);\n */\n}\n\nvoid platform_init() {\n initRandomSeed();\n setSendToUART(platformSendSerial);\n\n // make sure sound doesn't draw power before enabled\n set_if_present(CFG_PIN_JACK_SND, 0);\n set_if_present(CFG_PIN_JACK_HPEN, 0);\n set_if_present(CFG_PIN_JACK_BZEN, 1);\n\n /*\n if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n *HF2_DBG_MAGIC_PTR = 0;\n // this will cause alignment fault at the first breakpoint\n globals[0] = (TValue)1;\n }\n */\n}\n\nint *getBootloaderConfigData() {\n#ifdef STM32F4\n auto config_data = (uint32_t)(UF2_BINFO->configValues);\n if (config_data && (config_data & 3) == 0) {\n auto p = (uint32_t *)config_data - 4;\n if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1)\n return (int *)p + 4;\n }\n#endif\n\n return NULL;\n}\n\n#define STM32_UUID ((uint32_t *)0x1FFF7A10)\n\n#if CONFIG_ENABLED(DEVICE_USB)\nstatic void writeHex(char *buf, uint32_t n) {\n int i = 0;\n int sh = 28;\n while (sh >= 0) {\n int d = (n >> sh) & 0xf;\n buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d;\n sh -= 4;\n }\n buf[i] = 0;\n}\n#endif\n\nvoid platform_usb_init() {\n#if CONFIG_ENABLED(DEVICE_USB)\n static char serial_number[25];\n\n writeHex(serial_number, STM32_UUID[0]);\n writeHex(serial_number + 8, STM32_UUID[1]);\n writeHex(serial_number + 16, STM32_UUID[2]);\n\n usb.stringDescriptors[2] = serial_number;\n#endif\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {}\n", "platform.h": "#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"MultiButton.h\"\n#include \"STM32I2C.h\"\n#include \"STM32Pin.h\"\n#include \"STM32SPI.h\"\n#include \"STM32Serial.h\"\n#include \"Timer.h\"\n\n#include \"pinmap.h\"\n\n#define BOOTLOADER_START 0x08000000\n#define BOOTLOADER_END 0x08008000\n\n#ifdef STM32F4\n#define SETTINGS_MAGIC_0 0x10476643\n#define SETTINGS_MAGIC_1 0x2e9a5026\n\nstruct F4_Settings {\n uint32_t magic0;\n uint32_t magic1;\n int *configValues;\n uint32_t hseValue;\n const char *info_uf2;\n const char *manufacturer;\n const char *device;\n uint32_t reserved[16 - 7];\n};\n\n#define UF2_BINFO ((F4_Settings *)(BOOTLOADER_END - sizeof(F4_Settings)))\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#define USB_HANDOVER 0\n\n#define BOOT_RTC_SIGNATURE 0x71a21877\n#define APP_RTC_SIGNATURE 0x24a22d12\n#define HF2_RTC_SIGNATURE 0x39a63a78\n#define QUICK_BOOT(v) \\\n do { \\\n RTC->BKP0R = v ? APP_RTC_SIGNATURE : HF2_RTC_SIGNATURE; \\\n } while (0)\n#else\n#define QUICK_BOOT(v) ((void)0)\n#endif\n\n#define PAGE_SIZE 1024 // not really\n\n#define DEV_NUM_PINS 64\n\n#ifdef STM32F1\n#define DEV_PWM_PINS 0b111100000011101100001110111000111111001110LL\n#else\n#define DEV_PWM_PINS 0b111100000011100111111110111000111111101111LL\n#endif\n\n// CCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAA\n// fedcba9876543210fedcba9876543210fedcba9876543210\n#define DEV_AIN_PINS 0b000011111100000000000000110000000011111111LL\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_SERIAL codal::STM32Serial\n#define CODAL_PIN codal::STM32Pin\n#define CODAL_TIMER Timer\n#define CODAL_SPI codal::STM32SPI\n#define CODAL_I2C codal::STM32I2C\n#define CODAL_JACDAC_WIRE_SERIAL codal::ZSingleWireSerial\n\n#define PERF_NOW() (TIM5->CNT)\n\n#define IMAGE_BITS 4\n\n#define ALT0 0x000\n#define ALT1 0x100\n#define ALT2 0x200\n\n// The parameters below needs tuning!\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n\n#define PA_0 0x00\n#define PA_0_ALT0 PA_0 | ALT0\n#define PA_1 0x01\n#define PA_1_ALT0 PA_1 | ALT0\n#define PA_2 0x02\n#define PA_2_ALT0 PA_2 | ALT0\n#define PA_3 0x03\n#define PA_3_ALT0 PA_3 | ALT0\n#define PA_4 0x04\n#define PA_4_ALT0 PA_4 | ALT0\n#define PA_5 0x05\n#define PA_5_ALT0 PA_5 | ALT0\n#define PA_6 0x06\n#define PA_6_ALT0 PA_6 | ALT0\n#define PA_7 0x07\n#define PA_7_ALT0 PA_7 | ALT0\n#define PA_7_ALT1 PA_7 | ALT1\n#define PA_7_ALT2 PA_7 | ALT2\n#define PA_8 0x08\n#define PA_9 0x09\n#define PA_10 0x0A\n#define PA_11 0x0B\n#define PA_12 0x0C\n#define PA_13 0x0D\n#define PA_14 0x0E\n#define PA_15 0x0F\n#define PA_15_ALT0 PA_15 | ALT0\n#define PB_0 0x10\n#define PB_0_ALT0 PB_0 | ALT0\n#define PB_0_ALT1 PB_0 | ALT1\n#define PB_1 0x11\n#define PB_1_ALT0 PB_1 | ALT0\n#define PB_1_ALT1 PB_1 | ALT1\n#define PB_2 0x12\n#define PB_3 0x13\n#define PB_3_ALT0 PB_3 | ALT0\n#define PB_4 0x14\n#define PB_4_ALT0 PB_4 | ALT0\n#define PB_5 0x15\n#define PB_5_ALT0 PB_5 | ALT0\n#define PB_6 0x16\n#define PB_6_ALT0 PB_6 | ALT0\n#define PB_7 0x17\n#define PB_7_ALT0 PB_7 | ALT0\n#define PB_8 0x18\n#define PB_8_ALT0 PB_8 | ALT0\n#define PB_9 0x19\n#define PB_9_ALT0 PB_9 | ALT0\n#define PB_10 0x1A\n#define PB_11 0x1B\n#define PB_12 0x1C\n#define PB_13 0x1D\n#define PB_13_ALT0 PB_13 | ALT0\n#define PB_14 0x1E\n#define PB_14_ALT0 PB_14 | ALT0\n#define PB_14_ALT1 PB_14 | ALT1\n#define PB_15 0x1F\n#define PB_15_ALT0 PB_15 | ALT0\n#define PB_15_ALT1 PB_15 | ALT1\n#define PC_0 0x20\n#define PC_0_ALT0 PC_0 | ALT0\n#define PC_0_ALT1 PC_0 | ALT1\n#define PC_1 0x21\n#define PC_1_ALT0 PC_1 | ALT0\n#define PC_1_ALT1 PC_1 | ALT1\n#define PC_2 0x22\n#define PC_2_ALT0 PC_2 | ALT0\n#define PC_2_ALT1 PC_2 | ALT1\n#define PC_3 0x23\n#define PC_3_ALT0 PC_3 | ALT0\n#define PC_3_ALT1 PC_3 | ALT1\n#define PC_4 0x24\n#define PC_4_ALT0 PC_4 | ALT0\n#define PC_5 0x25\n#define PC_5_ALT0 PC_5 | ALT0\n#define PC_6 0x26\n#define PC_6_ALT0 PC_6 | ALT0\n#define PC_7 0x27\n#define PC_7_ALT0 PC_7 | ALT0\n#define PC_8 0x28\n#define PC_8_ALT0 PC_8 | ALT0\n#define PC_9 0x29\n#define PC_9_ALT0 PC_9 | ALT0\n#define PC_10 0x2A\n#define PC_10_ALT0 PC_10 | ALT0\n#define PC_11 0x2B\n#define PC_11_ALT0 PC_11 | ALT0\n#define PC_12 0x2C\n#define PC_13 0x2D\n#define PC_14 0x2E\n#define PC_15 0x2F\n#define PD_0 0x30\n#define PD_1 0x31\n#define PD_2 0x32\n#define PD_3 0x33\n#define PD_4 0x34\n#define PD_5 0x35\n#define PD_6 0x36\n#define PD_7 0x37\n#define PD_8 0x38\n#define PD_9 0x39\n#define PD_10 0x3A\n#define PD_11 0x3B\n#define PD_12 0x3C\n#define PD_13 0x3D\n#define PD_14 0x3E\n#define PD_15 0x3F\n#define PE_0 0x40\n#define PE_1 0x41\n#define PE_2 0x42\n#define PE_3 0x43\n#define PE_4 0x44\n#define PE_5 0x45\n#define PE_6 0x46\n#define PE_7 0x47\n#define PE_8 0x48\n#define PE_9 0x49\n#define PE_10 0x4A\n#define PE_11 0x4B\n#define PE_12 0x4C\n#define PE_13 0x4D\n#define PE_14 0x4E\n#define PE_15 0x4F\n\n#endif\n\n#endif\n", "pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n", - "pxt.json": "{\n \"name\": \"core---stm32\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"core---stm32\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", "pxtcore.h": "#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n", "pxtparts.json": "{\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 19,\n \"y\": 0\n },\n {\n \"x\": 28,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"dotstar\": {\n \"simulationBehavior\": \"dotstar\",\n \"visual\": {\n \"builtIn\": \"dotstar\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 1\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createAPA102Strip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"dataPin\"\n },\n {\n \"pinInstantiationIdx\": 1,\n \"partParameter\": \"clkPin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n },\n \"pixels\": {\n \"simulationBehavior\": \"pixels\",\n \"visual\": { \n \"builtIn\": \"pixels\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"MOSI\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCK\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n }, \n \"buttons\": {\n \"simulationBehavior\": \"buttons\",\n \"visual\": {\n \"builtIn\": \"buttons\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 45\n }\n ]\n },\n \"numberOfPins\": 2,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"button\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"slideswitch\": {\n \"numberOfPins\": 3,\n \"simulationBehavior\": \"slideswitch\",\n \"visual\": {\n \"builtIn\": \"slideswitch\",\n \"width\": 100,\n \"height\": 100,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 0\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 5\n },\n {\n \"x\": 37,\n \"y\": 5\n },\n {\n \"x\": 45,\n \"y\": 5\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"led\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"analogled\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"photocell\": {\n \"numberOfPins\": 3,\n \"visual\": {\n \"builtIn\": \"photocell\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 15,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"photocell\",\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n }\n}", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace light {\n\n /**\n * Send a programmable light buffer to the specified digital pin\n * @param data The pin that the lights are connected to\n * @param clk the clock line if any\n * @param mode the color encoding mode\n * @param buf The buffer to send to the pin\n */\n //% shim=light::sendBuffer\n function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n /**\n * Determines if the USB has been enumerated.\n */\n //% shim=control::isUSBInitialized\n function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n /**\n * Get a pin by configuration id (DAL.CFG_PIN...)\n */\n //% shim=pins::pinByCfg\n function pinByCfg(key: int32): DigitalInOutPin;\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=pins::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration blockGap=8\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=19 shim=pins::pulseDuration\n function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read weight=53\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n //% blockNamespace=pins\n //% parts=\"photocell\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=AnalogInPinMethods::analogRead\n analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write weight=52\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n //% blockNamespace=pins\n //%parts=\"analogled\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.min=0 value.max=1023\n //% trackArgs=0 shim=AnalogOutPinMethods::analogWrite\n analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read weight=61\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalRead\n digitalRead(): boolean;\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin\n */\n //% help=pins/digital-write weight=60\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n //% parts=\"led\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalWrite\n digitalWrite(value: boolean): void;\n\n /**\n * Make this pin a digital input, and create events where the timestamp is the duration\n * that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=16 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n onPulsed(pulse: PulseValue, body: () => void): void;\n\n /**\n * Register code to run when a pin event occurs.\n */\n //% help=pins/on-event weight=20 blockGap=8\n //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::onEvent\n onEvent(event: PinEvent, body: () => void): void;\n\n /**\n * Return the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %high||timeout %maxDuration (µs)\"\n //% weight=18 blockGap=8\n //% help=\"pins/pulse-in\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n /**\n * Set the pull direction of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone\n */\n //% help=pins/set-pull weight=17 blockGap=8\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n /**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=51\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n analogSetPeriod(period: int32): void;\n\n /**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed\n */\n //% help=pins/servo-write weight=41 group=\"Servo\"\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n //% parts=microservo trackArgs=0\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n servoWrite(value?: int32): void;\n\n /**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n //% parts=microservo blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n servoSetPulse(duration: int32): void;\n\n /**\n * Indicates if the servo is running continuously\n */\n //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n /**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n //% help=control/raise-event\n //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n function raiseEvent(src: int32, value: int32): void;\n\n /**\n * Determine the version of system software currently running.\n */\n //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n //% help=control/device-dal-version shim=control::deviceDalVersion\n function deviceDalVersion(): string;\n\n /**\n * Allocates the next user notification event\n */\n //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n function allocateNotifyEvent(): int32;\n\n /** Write a message to DMESG debugging buffer. */\n //% shim=control::dmesg\n function dmesg(s: string): void;\n\n /** Write a message and value (pointer) to DMESG debugging buffer. */\n //% shim=control::dmesgPtr\n function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::readBuffer\n readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::writeBuffer\n writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n /**\n * Opens a Serial communication driver\n */\n //% help=pins/create-i2c\n //% parts=i2c shim=pins::createI2C\n function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n /**\n * Opens a SPI driver\n */\n //% help=pins/create-spi\n //% parts=spi shim=pins::createSPI\n function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n /**\n * Opens a slave SPI driver\n */\n //% parts=spi shim=pins::createSlaveSPI\n function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n /**\n * Write to the SPI bus\n */\n //% shim=SPIMethods::write\n write(value: int32): int32;\n\n /**\n * Transfer buffers over the SPI bus\n */\n //% argsNullable shim=SPIMethods::transfer\n transfer(command: Buffer, response: Buffer): void;\n\n /**\n * Sets the SPI clock frequency\n */\n //% shim=SPIMethods::setFrequency\n setFrequency(frequency: int32): void;\n\n /**\n * Sets the SPI bus mode\n */\n //% shim=SPIMethods::setMode\n setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n /**\n * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n * @param value the data (max 32 characters)\n */\n //% shim=configStorage::setBuffer\n function setBuffer(key: string, value: Buffer): void;\n\n /**\n * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::getBuffer\n function getBuffer(key: string): Buffer;\n\n /**\n * Removes the key from local storage\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::removeItem\n function removeItem(key: string): void;\n\n /**\n * Clears the local storage\n */\n //% shim=configStorage::clear\n function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -749,13 +750,13 @@ var pxtTargetBundle = { "config.ts": "namespace config {\n \n // ====================================================\n // === UART =======================================\n // ================================================\n export const PIN_UART1_TX = DAL.PB_6;\n export const PIN_UART1_RX = DAL.PB_7;\n \n export const PIN_UART2_TX = DAL.PD_5;\n export const PIN_UART2_RX = DAL.PD_6;\n \n export const PIN_UART3_TX = DAL.PD_8;\n export const PIN_UART3_RX = DAL.PD_9;\n \n export const PIN_UART4_TX = DAL.PA_0;\n export const PIN_UART4_RX = DAL.PA_1;\n \n\n // ====================================================\n // === SPI ========================================\n // ================================================\n export const PIN_SPI1_MISO = DAL.PA_6;\n export const PIN_SPI1_MOSI = DAL.PA_7_ALT1;\n export const PIN_SPI1_SCK = DAL.PA_5;\n \n export const PIN_SPI2_MISO = DAL.PD_3;\n export const PIN_SPI2_MOSI = DAL.PD_4;\n export const PIN_SPI2_SCK = DAL.PD_1;\n \n export const PIN_SPI3_MISO = DAL.PC_11;\n export const PIN_SPI3_MOSI = DAL.PC_12;\n export const PIN_SPI3_SCK = DAL.PC_10;\n\n\n // ====================================================\n // === I2C ========================================\n // ================================================\n export const PIN_I2C1_SCL = DAL.PB_8;\n export const PIN_I2C1_SDA = DAL.PB_9;\n \n export const PIN_I2C2_SCL = DAL.PB_10;\n export const PIN_I2C2_SDA = DAL.PB_11;\n\n \n // ====================================================\n // === PERIPHERALS ================================\n // ================================================\n export const PIN_ACCELEROMETER_SDA = PIN_I2C2_SDA;\n export const PIN_ACCELEROMETER_SCL = PIN_I2C2_SCL;\n export const PIN_ACCELEROMETER_INT = DAL.PD_11; \n\n export const PIN_HTS221_SDA = PIN_I2C2_SDA;\n export const PIN_HTS221_SCL = PIN_I2C2_SCL;\n\n export const PIN_LPS22HB_SDA = PIN_I2C2_SDA;\n export const PIN_LPS22HB_SCL = PIN_I2C2_SCL;\n\n export const PIN_VL53L0X_SDA = PIN_I2C2_SDA;\n export const PIN_VL53L0X_SCL = PIN_I2C2_SCL;\n export const PIN_VL53L0X_SHUT = DAL.PC_6;\n\n export const PIN_LSM6DSL_SDA = PIN_I2C2_SDA;\n export const PIN_LSM6DSL_SCL = PIN_I2C2_SCL;\n\n export const PIN_BLE_SPI_MOSI = PIN_SPI3_MOSI;\n export const PIN_BLE_SPI_MISO = PIN_SPI3_MISO;\n export const PIN_BLE_SPI_SCLK = PIN_SPI3_SCK;\n\n export const PIN_BLE_SPI_CS = DAL.PD_13;\n export const PIN_BLE_SPI_IRQ = DAL.PE_6;\n export const PIN_BLE_RST = DAL.PA_8;\n\n export const PIN_WIFI_ISM43362_MOSI = PIN_SPI3_MOSI;\n export const PIN_WIFI_ISM43362_MISO = PIN_SPI3_MISO;\n export const PIN_WIFI_ISM43362_SCK = PIN_SPI3_SCK;\n \n export const PIN_WIFI_ISM43362_CS = DAL.PE_0;\n export const PIN_WIFI_ISM43362_COMMAND_DATA_READY = DAL.PE_1;\n export const PIN_WIFI_ISM43362_RESET = DAL.PE_8;\n export const PIN_WIFI_ISM43362_WAKE_UP = DAL.PB_13;\n \n\n // ====================================================\n // === ARDUINO ====================================\n // ================================================\n export const PIN_A0 = DAL.PC_5;\n export const PIN_A1 = DAL.PC_4;\n export const PIN_A2 = DAL.PC_3;\n export const PIN_A3 = DAL.PC_2;\n export const PIN_A4 = DAL.PC_1;\n export const PIN_A5 = DAL.PC_0;\n\n export const PIN_D0 = DAL.PA_1;\n export const PIN_D1 = DAL.PA_0;\n export const PIN_D2 = DAL.PD_14;\n export const PIN_D3 = DAL.PB_0_ALT1;\n export const PIN_D4 = DAL.PA_3;\n export const PIN_D5 = DAL.PB_4;\n export const PIN_D6 = DAL.PB_1_ALT1;\n export const PIN_D7 = DAL.PA_4;\n export const PIN_D8 = DAL.PB_2;\n export const PIN_D9 = DAL.PA_15;\n export const PIN_D10 = DAL.PA_2;\n export const PIN_D11 = DAL.PA_7_ALT1;\n export const PIN_D12 = DAL.PA_6;\n export const PIN_D13 = DAL.PA_5;\n export const PIN_D14 = DAL.PB_9;\n export const PIN_D15 = DAL.PB_8;\n\n export const PIN_RX = PIN_UART1_RX;\n export const PIN_TX = PIN_UART1_TX;\n\n export const PIN_MISO = PIN_SPI1_MISO;\n export const PIN_MOSI = PIN_SPI1_MOSI;\n export const PIN_SCK = PIN_SPI1_SCK;\n\n export const PIN_SCL = PIN_I2C1_SCL;\n export const PIN_SDA = PIN_I2C1_SDA;\n\n\n // ====================================================\n // === ON-BOARD COMPONENTS ========================\n // ================================================\n export const PIN_LED = DAL.PA_5;\n export const PIN_LED2 = DAL.PB_14;\n export const PIN_LED3 = DAL.PC_9;\n\n export const PIN_BTN_USER = DAL.PC_13;\n export const PIN_RESET = DAL.NO_CONN;\n export const PIN_TEMPERATURE = DAL.NO_CONN;\n\n\n // ====================================================\n // === EXTERNAL DEFINITION ========================\n // ================================================\n export const PIN_SPEAKER_AMP = PIN_D3;\n}\n", "device.d.ts": "declare namespace pins {\n //% fixedInstance shim=pxt::getPin(PIN_A0)\n const A0: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A1)\n const A1: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A2)\n const A2: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A3)\n const A3: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A4)\n const A4: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A5)\n const A5: AnalogInPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_D0)\n const D0: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D1)\n const D1: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D2)\n const D2: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D3)\n const D3: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D4)\n const D4: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D5)\n const D5: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D6)\n const D6: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D7)\n const D7: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_D8)\n const D8: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D9)\n const D9: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D10)\n const D10: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D11)\n const D11: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D12)\n const D12: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D13)\n const D13: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D14)\n const D14: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D15)\n const D15: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_LED)\n const LED: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_LED2)\n const LED2: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_LED3)\n const LED3: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_RX)\n const RX: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_TX)\n const TX: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_MISO)\n const MISO: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_MOSI)\n const MOSI: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SCK)\n const SCK: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SCL)\n const SCL: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SDA)\n const SDA: DigitalInOutPin;\n}\n\ndeclare namespace input {\n /**\n * Button connecting A0 to GND.\n */\n //% block=\"button A0\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A0,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA0: Button;\n\n /**\n * Button connecting A1 to GND.\n */\n //% block=\"button A1\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A1,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA1: Button;\n\n /**\n * Button connecting A2 to GND.\n */\n //% block=\"button A2\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A2,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA2: Button;\n\n /**\n * Button connecting A3 to GND.\n */\n //% block=\"button A3\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A3,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA3: Button;\n\n /**\n * Button connecting A4 to GND.\n */\n //% block=\"button A4\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A4,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA4: Button;\n\n /**\n * Button connecting A5 to GND.\n */\n //% block=\"button A5\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A5,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA5: Button;\n\n /**\n * Button connecting D0 to GND.\n */\n //% block=\"button D0\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D0,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD0: Button;\n\n /**\n * Button connecting D1 to GND.\n */\n //% block=\"button D1\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D1,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD1: Button;\n\n /**\n * Button connecting D2 to GND.\n */\n //% block=\"button D2\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D2,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD2: Button;\n\n /**\n * Button connecting D3 to GND.\n */\n //% block=\"button D3\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D3,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD3: Button;\n\n /**\n * Button connecting D4 to GND.\n */\n //% block=\"button D4\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D4,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD4: Button;\n\n /**\n * Button connecting D5 to GND.\n */\n //% block=\"button D5\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D5,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD5: Button;\n\n /**\n * Button connecting D6 to GND.\n */\n //% block=\"button D6\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D6,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD6: Button;\n\n /**\n * Button connecting D7 to GND.\n */\n //% block=\"button D7\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D7,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD7: Button;\n\n /**\n * Button connecting D8 to GND.\n */\n //% block=\"button D8\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D8,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD8: Button;\n\n /**\n * Button connecting D9 to GND.\n */\n //% block=\"button D9\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D9,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD9: Button;\n\n /**\n * Button connecting D10 to GND.\n */\n //% block=\"button D10\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D10,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD10: Button;\n\n /**\n * Button connecting D11 to GND.\n */\n //% block=\"button D11\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D11,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD11: Button;\n\n /**\n * Button connecting D12 to GND.\n */\n //% block=\"button D12\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D12,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD12: Button;\n\n /**\n * Button connecting D13 to GND.\n */\n //% block=\"button D13\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D13,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD13: Button;\n\n /**\n * Button connecting BTN_USER to GND.\n */\n //% block=\"button USER\" fixedInstance\n //% shim=pxt::getButton(0)\n const buttonUser: Button;\n}\n", "ns.ts": "//% color=\"#d65cd6\" weight=90\n//% groups='[\"Buttons\", \"Temperature\", \"Humidity\", \"Pressure\", \"Distance\", \"Movement\"]'\nnamespace input {\n}\n\n//% color=\"#EF2D56\" weight=80 advanced=false\nnamespace pins {\n}\n\n//% color=\"#00b295\" weight=70 advanced=true\nnamespace control {\n\n}\n\n//% color=\"#61b22f\" weight=70 \nnamespace loops {\n\n}\n\n//% color=\"#006E90\" weight=30 icon=\"\\uf1e6\" advanced=false\nnamespace serial {\n\n}", - "pxt.json": "{\n \"name\": \"stm32-discovery-DISCO_L475VG_IOT\",\n \"description\": \"DISCO_L475VG_IOT - beta\",\n \"dependencies\": {\n \"accelerometer---lsm6dsl\": \"*\",\n \"barometer---lps22hb\": \"*\",\n \"buttons\": \"*\",\n \"core---stm32\": \"*\",\n \"distance---vl53l0x\": \"*\",\n \"hygrometer---hts221\": \"*\",\n \"thermometer---lps22hb\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"ns.ts\",\n \"config.ts\",\n \"device.d.ts\",\n \"board.json\",\n \"board.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"compileServiceVariant\": \"stm32-DISCO_L475VG_IOT\",\n \"core\": true,\n \"dalDTS\": {\n \"corePackage\": \"../core---stm32\"\n },\n \"features\": [\n \"pina0\",\n \"pina1\"\n ],\n \"icon\": \"/docs/static/libs/stm32-discovery-DISCO_L475VG_IOT.jpg\"\n}\n" + "pxt.json": "{\n \"name\": \"stm32-discovery-DISCO_L475VG_IOT\",\n \"description\": \"DISCO_L475VG_IOT - beta\",\n \"dependencies\": {\n \"accelerometer---lsm6dsl\": \"*\",\n \"barometer---lps22hb\": \"*\",\n \"buttons\": \"*\",\n \"core---stm32\": \"*\",\n \"distance---vl53l0x\": \"*\",\n \"hygrometer---hts221\": \"*\",\n \"thermometer---lps22hb\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"ns.ts\",\n \"config.ts\",\n \"device.d.ts\",\n \"board.json\",\n \"board.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"compileServiceVariant\": \"stm32-DISCO_L475VG_IOT\",\n \"core\": true,\n \"dalDTS\": {\n \"corePackage\": \"../core---stm32\"\n },\n \"features\": [\n \"pina0\",\n \"pina1\"\n ],\n \"icon\": \"/docs/static/libs/stm32-discovery-DISCO_L475VG_IOT.jpg\"\n}\n" }, "buttons": { "README.md": "# buttons\n\nA library to handle 2 buttons A and B.\n", "buttons.cpp": "#include \"pxt.h\"\n\n/*\nThese button events need CODAL work.\n // % block=\"double click\"\n DoubleClick = DEVICE_BUTTON_EVT_DOUBLE_CLICK,\n // % block=\"hold\"\n Hold = DEVICE_BUTTON_EVT_HOLD\n*/\n\n/**\n * User interaction on buttons\n */\nenum class ButtonEvent {\n //% block=\"click\"\n Click = DEVICE_BUTTON_EVT_CLICK,\n //% block=\"long click\"\n LongClick = DEVICE_BUTTON_EVT_LONG_CLICK,\n //% block=\"up\"\n Up = DEVICE_BUTTON_EVT_UP,\n //% block=\"down\"\n Down = DEVICE_BUTTON_EVT_DOWN\n};\n\nnamespace pxt {\n//%\nButton *getButtonByPin(int pin, int flags) {\n auto cpid = DEVICE_ID_FIRST_BUTTON + pin;\n auto btn = (Button *)lookupComponent(cpid);\n if (btn == NULL) {\n auto pull = PullMode::None;\n if ((flags & 0xf0) == 0x10)\n pull = PullMode::Down;\n else if ((flags & 0xf0) == 0x20)\n pull = PullMode::Up;\n else if ((flags & 0xf0) == 0x20)\n pull = PullMode::None;\n else\n target_panic(42);\n btn = new Button(*lookupPin(pin), cpid, DEVICE_BUTTON_ALL_EVENTS, (ButtonPolarity)(flags & 0xf), pull);\n }\n return btn;\n}\n\n//%\nButton *getButtonByPinCfg(int key, int flags) {\n int pin = getConfig(key);\n if (pin == -1)\n target_panic(42);\n return getButtonByPin(pin, flags);\n}\n\nMultiButton *getMultiButton(int id, int pinA, int pinB, int flags) {\n auto btn = (MultiButton *)lookupComponent(id);\n if (btn == NULL) {\n auto bA = getButtonByPin(pinA, flags);\n auto bB = getButtonByPin(pinB, flags);\n btn = new codal::MultiButton(bA->id, bB->id, id);\n\n // A user has registered to receive events from the buttonAB multibutton.\n // Disable click events from being generated by ButtonA and ButtonB, and defer the\n // control of this to the multibutton handler.\n //\n // This way, buttons look independent unless a buttonAB is requested, at which\n // point button A+B clicks can be correclty handled without breaking\n // causal ordering.\n bA->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n bB->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n btn->setEventConfiguration(DEVICE_BUTTON_ALL_EVENTS);\n }\n return btn;\n}\n\n// This is for A, B, and AB\n//%\nAbstractButton *getButton(int id) {\n // int pa = getConfig(CFG_PIN_BTN_A);\n // int pb = getConfig(CFG_PIN_BTN_B);\n // int flags = getConfig(CFG_DEFAULT_BUTTON_MODE, BUTTON_ACTIVE_LOW_PULL_UP);\n // if (id == 0)\n // return getButtonByPin(pa, flags);\n // else if (id == 1)\n // return getButtonByPin(pb, flags);\n // else if (id == 2)\n // return getMultiButton(DEVICE_ID_BUTTON_AB, pa, pb, flags);\n // else {\n // target_panic(42);\n // return NULL;\n // }\n\n int pUser = getConfig(CFG_PIN_BTN_USER);\n int flags = getConfig(CFG_DEFAULT_BUTTON_MODE, BUTTON_ACTIVE_LOW_PULL_UP);\n\n if (id == 0) {\n return getButtonByPin(pUser, flags);\n } else {\n target_panic(42);\n return NULL;\n }\n}\n\n} // namespace pxt\n\nnamespace DigitalInOutPinMethods {\n\n/**\n * Get the push button (connected to GND) for given pin\n */\n//%\nButton_ pushButton(DigitalInOutPin pin) {\n return pxt::getButtonByPin((uint8_t)pin->name, BUTTON_ACTIVE_LOW_PULL_UP);\n}\n\n} // namespace DigitalInOutPinMethods\n\n//% noRefCounting fixedInstances\nnamespace ButtonMethods {\n\n/**\n * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n * @param button the button that needs to be clicked or used\n * @param event the kind of button gesture that needs to be detected\n * @param body code to run when the event is raised\n */\n//% help=input/button/on-event\n//% blockId=buttonEvent block=\"on %button|%event\"\n//% parts=\"buttons\"\n//% group=\"Buttons\"\n//% blockNamespace=input\n//% weight=96 blockGap=12\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% trackArgs=0\nvoid onEvent(Button_ button, ButtonEvent ev, Action body) {\n registerWithDal(button->id, (int)ev, body);\n}\n\n/**\n * Check if a button is pressed or not.\n * @param button the button to query the request\n */\n//% help=input/button/is-pressed\n//% block=\"%button|is pressed\"\n//% blockId=buttonIsPressed\n//% parts=\"buttons\"\n//% group=\"Buttons\"\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=50 blockGap=8\n//% trackArgs=0\nbool isPressed(Button_ button) {\n return button->isPressed();\n}\n\n/**\n * See if the button was pressed again since the last time you checked.\n * @param button the button to query the request\n */\n//% help=input/button/was-pressed\n//% block=\"%button|was pressed\"\n//% blockId=buttonWasPressed\n//% parts=\"buttons\"\n//% group=\"Buttons\" advanced=true\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=46 blockGap=8\n//% trackArgs=0\nbool wasPressed(Button_ button) {\n return button->wasPressed();\n}\n\n/**\n * Gets the component identifier for the buton\n */\n//%\nint id(Button_ button) {\n return button->id;\n}\n\n} // namespace ButtonMethods", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * User interaction on buttons\n */\n\n declare const enum ButtonEvent {\n //% block=\"click\"\n Click = 3, // DEVICE_BUTTON_EVT_CLICK\n //% block=\"long click\"\n LongClick = 4, // DEVICE_BUTTON_EVT_LONG_CLICK\n //% block=\"up\"\n Up = 2, // DEVICE_BUTTON_EVT_UP\n //% block=\"down\"\n Down = 1, // DEVICE_BUTTON_EVT_DOWN\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"buttons\",\n \"description\": \"Button A and B drivers\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"buttons.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"buttons\",\n \"description\": \"Button A and B drivers\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"buttons.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Get the push button (connected to GND) for given pin\n */\n //% shim=DigitalInOutPinMethods::pushButton\n pushButton(): Button;\n}\n\n\n\n //% noRefCounting fixedInstances\ndeclare interface Button {\n /**\n * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n * @param button the button that needs to be clicked or used\n * @param event the kind of button gesture that needs to be detected\n * @param body code to run when the event is raised\n */\n //% help=input/button/on-event\n //% blockId=buttonEvent block=\"on %button|%event\"\n //% parts=\"buttons\"\n //% group=\"Buttons\"\n //% blockNamespace=input\n //% weight=96 blockGap=12\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% trackArgs=0 shim=ButtonMethods::onEvent\n onEvent(ev: ButtonEvent, body: () => void): void;\n\n /**\n * Check if a button is pressed or not.\n * @param button the button to query the request\n */\n //% help=input/button/is-pressed\n //% block=\"%button|is pressed\"\n //% blockId=buttonIsPressed\n //% parts=\"buttons\"\n //% group=\"Buttons\"\n //% blockNamespace=input\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% weight=50 blockGap=8\n //% trackArgs=0 shim=ButtonMethods::isPressed\n isPressed(): boolean;\n\n /**\n * See if the button was pressed again since the last time you checked.\n * @param button the button to query the request\n */\n //% help=input/button/was-pressed\n //% block=\"%button|was pressed\"\n //% blockId=buttonWasPressed\n //% parts=\"buttons\"\n //% group=\"Buttons\" advanced=true\n //% blockNamespace=input\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% weight=46 blockGap=8\n //% trackArgs=0 shim=ButtonMethods::wasPressed\n wasPressed(): boolean;\n\n /**\n * Gets the component identifier for the buton\n */\n //% shim=ButtonMethods::id\n id(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "test.ts": "" }, @@ -768,14 +769,14 @@ var pxtTargetBundle = { "music.ts": "enum Note {\n //% blockIdentity=music.noteFrequency enumval=262\n C = 262,\n //% block=C#\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F = 349,\n //% block=F#\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G = 392,\n //% block=G#\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B = 494,\n //% blockIdentity=music.noteFrequency enumval=131\n C3 = 131,\n //% block=C#3\n //% blockIdentity=music.noteFrequency enumval=139\n CSharp3 = 139,\n //% blockIdentity=music.noteFrequency enumval=147\n D3 = 147,\n //% blockIdentity=music.noteFrequency enumval=156\n Eb3 = 156,\n //% blockIdentity=music.noteFrequency enumval=165\n E3 = 165,\n //% blockIdentity=music.noteFrequency enumval=175\n F3 = 175,\n //% block=F#3\n //% blockIdentity=music.noteFrequency enumval=185\n FSharp3 = 185,\n //% blockIdentity=music.noteFrequency enumval=196\n G3 = 196,\n //% block=G#3\n //% blockIdentity=music.noteFrequency enumval=208\n GSharp3 = 208,\n //% blockIdentity=music.noteFrequency enumval=220\n A3 = 220,\n //% blockIdentity=music.noteFrequency enumval=233\n Bb3 = 233,\n //% blockIdentity=music.noteFrequency enumval=247\n B3 = 247,\n //% blockIdentity=music.noteFrequency enumval=262\n C4 = 262,\n //% block=C#4\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp4 = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D4 = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb4 = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E4 = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F4 = 349,\n //% block=F#4\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp4 = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G4 = 392,\n //% block=G#4\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp4 = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A4 = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb4 = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B4 = 494,\n //% blockIdentity=music.noteFrequency enumval=523\n C5 = 523,\n //% block=C#5\n //% blockIdentity=music.noteFrequency enumval=555\n CSharp5 = 555,\n //% blockIdentity=music.noteFrequency enumval=587\n D5 = 587,\n //% blockIdentity=music.noteFrequency enumval=622\n Eb5 = 622,\n //% blockIdentity=music.noteFrequency enumval=659\n E5 = 659,\n //% blockIdentity=music.noteFrequency enumval=698\n F5 = 698,\n //% block=F#5\n //% blockIdentity=music.noteFrequency enumval=740\n FSharp5 = 740,\n //% blockIdentity=music.noteFrequency enumval=784\n G5 = 784,\n //% block=G#5\n //% blockIdentity=music.noteFrequency enumval=831\n GSharp5 = 831,\n //% blockIdentity=music.noteFrequency enumval=880\n A5 = 880,\n //% blockIdentity=music.noteFrequency enumval=932\n Bb5 = 932,\n //% blockIdentity=music.noteFrequency enumval=988\n B5 = 988,\n}\n\nenum BeatFraction {\n //% block=1\n Whole = 1,\n //% block=\"1/2\"\n Half = 2,\n //% block=\"1/4\"\n Quarter = 4,\n //% block=\"1/8\"\n Eighth = 8,\n //% block=\"1/16\"\n Sixteenth = 16,\n //% block=\"2\"\n Double = 32,\n //% block=\"4\",\n Breve = 64,\n //% block=\"1/3\",\n Triplet = 128\n}\n\nnamespace music {\n\n let beatsPerMinute: number;\n\n /**\n * Play a tone.\n * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n */\n //% help=music/ring-tone\n //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n //% parts=\"headphone\" trackArgs=0\n //% blockNamespace=music inBasicCategory=true\n //% weight=75 blockGap=8\n //% group=\"Tone\"\n export function ringTone(frequency: number) {\n playTone(frequency, 0);\n }\n\n /**\n * Rest, or play silence, for some time (in milliseconds).\n * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n */\n //% help=music/rest\n //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n //% parts=\"headphone\" trackArgs=0\n //% blockNamespace=music\n //% weight=74\n //% group=\"Tone\"\n export function rest(ms: number) {\n playTone(0, Math.max(ms, 20));\n }\n\n function init() {\n if (!beatsPerMinute) beatsPerMinute = 120;\n }\n\n /**\n * Return the duration of a beat in milliseconds (the beat fraction).\n * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n */\n //% help=music/beat\n //% blockId=device_beat block=\"%fraction|beat\"\n //% weight=9 blockGap=8\n //% group=\"Tempo\"\n export function beat(fraction?: BeatFraction): number {\n init();\n if (fraction == null) fraction = BeatFraction.Whole;\n let beat = 60000 / beatsPerMinute;\n switch (fraction) {\n case BeatFraction.Half: beat /= 2; break;\n case BeatFraction.Quarter: beat /= 4; break;\n case BeatFraction.Eighth: beat /= 8; break;\n case BeatFraction.Sixteenth: beat /= 16; break;\n case BeatFraction.Double: beat *= 2; break;\n case BeatFraction.Breve: beat *= 4; break;\n case BeatFraction.Triplet: beat /= 3; break;\n }\n return beat >> 0;\n }\n\n /**\n * Return the tempo in beats per minute (bpm).\n * Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.\n */\n //% help=music/tempo\n //% blockId=device_tempo block=\"tempo (bpm)\"\n //% weight=64\n //% group=\"Tempo\"\n export function tempo(): number {\n init();\n return beatsPerMinute;\n }\n\n /**\n * Change the tempo up or down by some amount of beats per minute (bpm).\n * @param bpm The change in beats per minute to the tempo, eg: 20\n */\n //% help=music/change-tempo-by weight=37\n //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n //% weight=66 blockGap=8\n //% group=\"Tempo\"\n export function changeTempoBy(bpm: number): void {\n init();\n setTempo(beatsPerMinute + bpm);\n }\n\n /**\n * Set the tempo a number of beats per minute (bpm).\n * @param bpm The new tempo in beats per minute, eg: 120\n */\n //% help=music/set-tempo\n //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n //% bpm.min=4 bpm.max=400\n //% weight=65 blockGap=8\n //% group=\"Tempo\"\n export function setTempo(bpm: number): void {\n init();\n if (bpm > 0) {\n beatsPerMinute = Math.max(1, bpm >> 0);\n }\n }\n}\n", "ns.ts": "\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Sounds\", \"Melody\", \"Tone\", \"Volume\", \"Tempo\"]'\nnamespace music {\n}", "piano.ts": "namespace music {\n /**\n * Get the frequency of a note.\n * @param name the note name, eg: Note.C\n */\n //% weight=1 help=music/note-frequency\n //% blockId=device_note block=\"%note\"\n //% shim=TD_ID\n //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n //% note.fieldEditor=\"note\" note.defl=\"262\"\n //% note.fieldOptions.decompileLiterals=true\n //% useEnumVal=1\n //% weight=10 blockGap=8\n //% group=\"Tone\"\n export function noteFrequency(name: Note): number {\n return name;\n }\n}", - "pxt.json": "{\n \"name\": \"music\",\n \"description\": \"The music library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"music.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"melodies.ts\",\n \"music.ts\",\n \"piano.ts\",\n \"ns.ts\",\n \"headphone.svg\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"music\",\n \"description\": \"The music library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"music.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"melodies.ts\",\n \"music.ts\",\n \"piano.ts\",\n \"ns.ts\",\n \"headphone.svg\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"headphone\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"headphone.svg\",\n \"width\": 142,\n \"height\": 180,\n \"pinDistance\": 20,\n \"pinLocations\": [\n {\n \"x\": 17,\n \"y\": 11\n },\n {\n \"x\": 55,\n \"y\": 50\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"D3\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [0]\n },\n {\n \"pinIndices\": [1]\n }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace music {\n\n /**\n * Play a tone through the speaker for some amount of time.\n * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n */\n //% help=music/play-tone\n //% blockId=music_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n //% parts=\"headphone\" async\n //% blockNamespace=music\n //% weight=76 blockGap=8 shim=music::playTone\n function playTone(frequency: int32, ms: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "test.ts": "for(let i = 1000; i > 0; i -= 50)\n music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n music.playTone(440, i)\n" }, "serial": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate57600 = 57600,\n //% block=38400\n BaudRate38400 = 38400,\n //% block=31250\n BaudRate31250 = 31250,\n //% block=28800\n BaudRate28800 = 28800,\n //% block=19200\n BaudRate19200 = 19200,\n //% block=14400\n BaudRate14400 = 14400,\n //% block=9600\n BaudRate9600 = 9600,\n //% block=4800\n BaudRate4800 = 4800,\n //% block=2400\n BaudRate2400 = 2400,\n //% block=1200\n BaudRate1200 = 1200,\n //% block=300\n BaudRate300 = 300,\n }\n\n\n declare const enum SerialEvent {\n //% block=\"data received\"\n DataReceived = 4, // CODAL_SERIAL_EVT_DATA_RECEIVED\n //% block=\"rx buffer full\"\n RxBufferFull = 3, // CODAL_SERIAL_EVT_RX_FULL\n }\n\n\n declare const enum Delimiters {\n //% block=\"new line (\\n)\"\n NewLine = 10,\n //% block=\",\"\n Comma = 44,\n //% block=\"$\"\n Dollar = 36,\n //% block=\":\"\n Colon = 58,\n //% block=\".\"\n Fullstop = 46,\n //% block=\"#\"\n Hash = 35,\n //% block=\"carriage return (\\r)\"\n CarriageReturn = 13,\n //% block=\"space\"\n Space = 32,\n //% block=\"tab (\\t)\"\n Tab = 9,\n //% block=\"|\"\n Pipe = 124,\n //% block=\";\"\n SemiColon = 59,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"serial\",\n \"description\": \"UART communication\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"serial-target.h\",\n \"serial-common.h\",\n \"serial-target.cpp\",\n \"serial-common.cpp\",\n \"serial-target.ts\",\n \"serial.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"serial\",\n \"description\": \"UART communication\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"serial-target.h\",\n \"serial-common.h\",\n \"serial-target.cpp\",\n \"serial-common.cpp\",\n \"serial-target.ts\",\n \"serial.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "serial-common.cpp": "#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace STMSerialDeviceMethods {\n/**\n * Sets the size of the RX buffer in bytes\n */\n//%\nvoid setRxBufferSize(Serial::STMSerialDevice device, uint8_t size) {\n device->setRxBufferSize(size);\n}\n\n/**\n * Sets the size of the TX buffer in bytes\n */\n//%\nvoid setTxBufferSize(Serial::STMSerialDevice device, uint8_t size) {\n device->setTxBufferSize(size);\n}\n\n/**\nSet the baud rate of the serial port\n*/\n//%\nvoid setBaudRate(Serial::STMSerialDevice device, BaudRate rate) {\n device->setBaudRate((int)rate);\n}\n\n/**\n * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n */\n//%\nint read(Serial::STMSerialDevice device) {\n return device->read();\n}\n\n/**\n * Read the buffered received data as a buffer\n */\n//%\nBuffer readBuffer(Serial::STMSerialDevice device) {\n return device->readBuffer();\n}\n\n/**\n * Send a buffer across the serial connection.\n */\n//%\nvoid writeBuffer(Serial::STMSerialDevice device, Buffer buffer) {\n device->writeBuffer(buffer);\n}\n\n/**\n * Register code when a serial event occurs\n */\n//%\nvoid onEvent(Serial::STMSerialDevice device, SerialEvent event, Action handler) {\n device->onEvent(event, handler);\n}\n\n/**\n * Registers code when a delimiter is received\n **/\n//%\nvoid onDelimiterReceived(Serial::STMSerialDevice device, Delimiters delimiter, Action handler) {\n device->onDelimiterReceived(delimiter, handler);\n}\n\n/**\n * Attach serial output to console\n *\n */\n//%\nvoid attachToConsole(Serial::STMSerialDevice device) {\n return;\n}\n\n} // namespace STMSerialDeviceMethods\n", "serial-common.h": "#pragma once\n#include \"pxt.h\"\n#include \"serial-target.h\"\n\nenum class BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate57600 = 57600,\n //% block=38400\n BaudRate38400 = 38400,\n //% block=31250\n BaudRate31250 = 31250,\n //% block=28800\n BaudRate28800 = 28800,\n //% block=19200\n BaudRate19200 = 19200,\n //% block=14400\n BaudRate14400 = 14400,\n //% block=9600\n BaudRate9600 = 9600,\n //% block=4800\n BaudRate4800 = 4800,\n //% block=2400\n BaudRate2400 = 2400,\n //% block=1200\n BaudRate1200 = 1200,\n //% block=300\n BaudRate300 = 300\n};\n\nenum class SerialEvent {\n //% block=\"data received\"\n DataReceived = CODAL_SERIAL_EVT_DATA_RECEIVED,\n //% block=\"rx buffer full\"\n RxBufferFull = CODAL_SERIAL_EVT_RX_FULL\n};\n\nenum class Delimiters {\n //% block=\"new line (\\n)\"\n NewLine = 10,\n //% block=\",\"\n Comma = 44,\n //% block=\"$\"\n Dollar = 36,\n //% block=\":\"\n Colon = 58,\n //% block=\".\"\n Fullstop = 46,\n //% block=\"#\"\n Hash = 35,\n //% block=\"carriage return (\\r)\"\n CarriageReturn = 13,\n //% block=\"space\"\n Space = 32,\n //% block=\"tab (\\t)\"\n Tab = 9,\n //% block=\"|\"\n Pipe = 124,\n //% block=\";\"\n SemiColon = 59,\n};\n\n", "serial-target.cpp": "#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace Serial {\n\nstatic STMSerialDevice serialDevices(NULL);\n/**\n * Opens a Serial communication driver\n */\n//%\nSTMSerialDevice internalCreateSerialDevice(DigitalInOutPin tx, DigitalInOutPin rx, int id) {\n auto dev = serialDevices;\n while (dev) {\n if (dev->matchPins(tx, rx))\n return dev;\n dev = dev->next;\n }\n\n // allocate new one\n auto ser = new CodalSTMSerialDeviceProxy(tx, rx, id);\n ser->next = serialDevices;\n serialDevices = ser;\n return ser;\n}\n\n} // namespace Serial\n\nnamespace STMSerialDeviceMethods {\n\n/**\n */\n//%\nvoid redirect(Serial::STMSerialDevice device, DigitalInOutPin tx, DigitalInOutPin rx, BaudRate rate) {\n device->redirect(tx, rx, rate);\n}\n\n} // namespace STMSerialDeviceMethods\n", @@ -788,7 +789,7 @@ var pxtTargetBundle = { "README.md": "# lcd\n\nPorted from STM32 lcd Support.\n", "lcd.cpp": "#include \"pxt.h\"\n#include \"target_lcd.h\"\n\nnamespace pxt {\nSINGLETON(WLCD);\n}\n\nnamespace lcd {\nuint8_t unpackR(uint32_t rgb) {\n uint8_t r = (rgb >> 16) & 0xFF;\n return r;\n}\nuint8_t unpackG(uint32_t rgb) {\n uint8_t g = (rgb >> 8) & 0xFF;\n return g;\n}\nuint8_t unpackB(uint32_t rgb) {\n uint8_t b = (rgb >> 0) & 0xFF;\n return b;\n}\n\n/**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"LCD_SET_CURSOR\"\n//% block=\"set cursor position |at x %x|y %y\"\n//% weight=89\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid setCursor(uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n//% blockId=\"LCD_SHOW_NUMBER\"\n//% block=\"show number %n\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowNumber(int n) {\n getWLCD()->lcd.print(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n//% blockId=\"LCD_SHOW_STRING\"\n//% block=\"show string %s\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowString(String s) {\n getWLCD()->lcd.print(s->getUTF8Data());\n}\n\n/**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n//% blockId=\"LCD_SHOW_VALUE\"\n//% block=\"show value %name = %value\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowValue(String name, int value) {\n getWLCD()->lcd.print(name->getUTF8Data());\n getWLCD()->lcd.print(':');\n getWLCD()->lcd.print(value);\n}\n\n/**\n * Clear all display content\n */\n//% blockId=\"LCD_CLEAR\"\n//% block=\"clear screen\"\n//% weight=85\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid clear() {\n getWLCD()->lcd.clear();\n}\n\n/**\n * Set lcd backlight color\n *\n * @param rgb RGB color of the backlight LED\n */\n//% blockId=\"LCD_BACKLIGHT_COLOR\"\n//% block=\"set backlight color %rgb=colorNumberPicker\"\n//% weight=69\n//% blockGap=8\n//% group=\"Backlight\"\n//% parts=lcd trackArgs=0\nvoid SetBacklightColor(uint32_t rgb) {\n uint8_t r = unpackR(rgb);\n uint8_t g = unpackG(rgb);\n uint8_t b = unpackB(rgb);\n getWLCD()->lcd.setRGB(r, g, b);\n}\n\n/**\n * Turn on lcd backlight\n */\n//% blockId=\"LCD_BACKLIGHT_ON\"\n//% block=\"turn on backlight\"\n//% group=\"Backlight\"\n//% weight=71\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid BacklightOn() {\n getWLCD()->lcd.setColorWhite();\n}\n\n/**\n * Turn off lcd backlight\n */\n//% blockId=\"LCD_BACKLIGHT_OFF\"\n//% block=\"turn off backlight\"\n//% group=\"Backlight\"\n//% weight=70\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid BacklightOff() {\n getWLCD()->lcd.setColorAll();\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"LCD_SHOW_NUMBER_AT_POS\"\n//% block=\"show number %n|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid ShowNumberAtPos(int n, uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n ShowNumber(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n//% blockId=\"LCD_SHOW_STRING_AT_POS\"\n//% block=\"show string %s|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid ShowStringAtPos(String s, uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n ShowString(s);\n}\n} // namespace lcd", "ns.ts": "/**\n * Character lcd support\n */\n//% icon=\"\\uf0ae\" color=\"#219E42\" blockGap=8\n//% groups='[\"Display\", \"Configuration\"]'\nnamespace lcd {\n\n}", - "pxt.json": "{\n \"name\": \"lcd\",\n \"description\": \"Support for I2C Characeter LCD display with RGB backlight\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"lcd\",\n \"description\": \"Support for I2C Characeter LCD display with RGB backlight\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"lcd\": {\n \"simulationBehavior\": \"lcd\",\n \"visual\": {\n \"builtIn\": \"lcd\",\n \"width\": 322.7900085449219,\n \"height\": 129.2734832763672,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 25,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 40,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 55,\n \"y\": 8.037069860858837\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"assembly\": [\n { \"part\": true },\n { \"pinIndices\": [0] },\n { \"pinIndices\": [1] },\n { \"pinIndices\": [2, 3] }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace lcd {\n\n /**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"LCD_SET_CURSOR\"\n //% block=\"set cursor position |at x %x|y %y\"\n //% weight=89\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::setCursor\n function setCursor(x: uint8, y: uint8): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n //% blockId=\"LCD_SHOW_NUMBER\"\n //% block=\"show number %n\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowNumber\n function ShowNumber(n: int32): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n //% blockId=\"LCD_SHOW_STRING\"\n //% block=\"show string %s\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowString\n function ShowString(s: string): void;\n\n /**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n //% blockId=\"LCD_SHOW_VALUE\"\n //% block=\"show value %name = %value\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowValue\n function ShowValue(name: string, value: int32): void;\n\n /**\n * Clear all display content\n */\n //% blockId=\"LCD_CLEAR\"\n //% block=\"clear screen\"\n //% weight=85\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::clear\n function clear(): void;\n\n /**\n * Set lcd backlight color\n *\n * @param rgb RGB color of the backlight LED\n */\n //% blockId=\"LCD_BACKLIGHT_COLOR\"\n //% block=\"set backlight color %rgb=colorNumberPicker\"\n //% weight=69\n //% blockGap=8\n //% group=\"Backlight\"\n //% parts=lcd trackArgs=0 shim=lcd::SetBacklightColor\n function SetBacklightColor(rgb: uint32): void;\n\n /**\n * Turn on lcd backlight\n */\n //% blockId=\"LCD_BACKLIGHT_ON\"\n //% block=\"turn on backlight\"\n //% group=\"Backlight\"\n //% weight=71\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::BacklightOn\n function BacklightOn(): void;\n\n /**\n * Turn off lcd backlight\n */\n //% blockId=\"LCD_BACKLIGHT_OFF\"\n //% block=\"turn off backlight\"\n //% group=\"Backlight\"\n //% weight=70\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::BacklightOff\n function BacklightOff(): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"LCD_SHOW_NUMBER_AT_POS\"\n //% block=\"show number %n|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::ShowNumberAtPos\n function ShowNumberAtPos(n: int32, x: uint8, y: uint8): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n //% blockId=\"LCD_SHOW_STRING_AT_POS\"\n //% block=\"show string %s|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::ShowStringAtPos\n function ShowStringAtPos(s: string, x: uint8, y: uint8): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_lcd.h": "#include \"pxt.h\"\n#include \"STM32I2C.h\"\n#include \"rgb_lcd.h\"\n\nnamespace pxt {\nclass WLCD {\n public:\n codal::STM32I2C i2c;\n codal::rgb_lcd lcd;\n WLCD() : i2c(*LOOKUP_PIN(SDA), *LOOKUP_PIN(SCL)), lcd(i2c, 16, 2) { lcd.init(); }\n};\n} // namespace pxt" @@ -797,7 +798,7 @@ var pxtTargetBundle = { "accelerometer.cpp": "#include \"CoordinateSystem.h\"\n#include \"I2C.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n#include \"target_accelerometer.h\"\n#include \"target_compass.h\"\n#include \"target_gyroscope.h\"\n\nenum class Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n};\n\nenum class Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n};\n\nenum class AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8\n};\n\nenum class Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = ACCELEROMETER_EVT_SHAKE,\n /**\n * Raised when the device tilts up\n */\n //% block=\"tilt up\"\n TiltUp = ACCELEROMETER_EVT_TILT_UP,\n /**\n * Raised when the device tilts down\n */\n //% block=\"tilt down\"\n TiltDown = ACCELEROMETER_EVT_TILT_DOWN,\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = ACCELEROMETER_EVT_TILT_LEFT,\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = ACCELEROMETER_EVT_TILT_RIGHT,\n /**\n * Raised when the screen faces up\n */\n //% block=\"face up\"\n FaceUp = ACCELEROMETER_EVT_FACE_UP,\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"face down\"\n FaceDown = ACCELEROMETER_EVT_FACE_DOWN,\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = ACCELEROMETER_EVT_FREEFALL,\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = ACCELEROMETER_EVT_3G,\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = ACCELEROMETER_EVT_6G,\n /**\n * Raised when a 8G shock is detected\n */\n //% block=\"8g\"\n EightG = ACCELEROMETER_EVT_8G\n};\n\nnamespace pxt {\n\nSINGLETON(WAccel);\nSINGLETON(WCompas);\nSINGLETON(WGyro);\n} // namespace pxt\n\nnamespace input {\n/**\n * Do something when a gesture happens (like shaking the board).\n * @param gesture the type of gesture to track, eg: Gesture.Shake\n * @param body code to run when gesture is raised\n */\n//% help=input/on-gesture\n//% blockId=device_gesture_event block=\"on |%NAME\"\n//% parts=\"accelerometer\"\n//% gesture.fieldEditor=\"gridpicker\"\n//% gesture.fieldOptions.width=220\n//% gesture.fieldOptions.columns=3\n//% group=\"Movement\"\n//% weight=92 blockGap=12\nvoid onGesture(Gesture gesture, Action body) {\n auto acc = getWAccel()->acc;\n acc->requestUpdate();\n int gi = (int)gesture;\n if (gi == ACCELEROMETER_EVT_3G && acc->getRange() < 3)\n acc->setRange(4);\n else if ((gi == ACCELEROMETER_EVT_6G || gi == ACCELEROMETER_EVT_8G) && acc->getRange() < 6)\n acc->setRange(8);\n registerWithDal(DEVICE_ID_GESTURE, gi, body);\n}\n\nint getAccelerationStrength() {\n auto acc = getWAccel()->acc;\n float x = acc->getX();\n float y = acc->getY();\n float z = acc->getZ();\n return (int)sqrtf(x * x + y * y + z * z);\n}\n\n/**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n * x=0, y=0 and z=-1023)\n * @param dimension TODO\n */\n//% help=input/acceleration\n//% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n//% parts=\"accelerometer\"\n//% dimension.fieldEditor=\"gridpicker\"\n//% dimension.fieldOptions.width=180\n//% dimension.fieldOptions.columns=2\n//% group=\"Movement\"\n//% weight=42 blockGap=8\nint acceleration(Dimension dimension) {\n switch (dimension) {\n case Dimension::X:\n return getWAccel()->acc->getX();\n case Dimension::Y:\n return getWAccel()->acc->getY();\n case Dimension::Z:\n return getWAccel()->acc->getZ();\n case Dimension::Strength:\n return getAccelerationStrength();\n }\n return 0;\n}\n\n/**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n//% help=input/rotation\n//% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n//% parts=\"accelerometer\"\n//% group=\"Movement\"\n//% weight=38\nint rotation(Rotation kind) {\n switch (kind) {\n case Rotation::Pitch:\n return getWAccel()->acc->getPitch();\n case Rotation::Roll:\n return getWAccel()->acc->getRoll();\n }\n return 0;\n}\n\n/**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n//% help=input/set-accelerometer-range\n//% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n//% weight=5 advanced=true\n//% parts=\"accelerometer\"\n//% group=\"Movement\"\n//% weight=15 blockGap=8\nvoid setAccelerometerRange(AcceleratorRange range) {\n getWAccel()->acc->setRange((int)range);\n}\n\n/**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the\n * simulator.\n * @param dimension TODO\n */\n//% help=input/magnetic-force weight=51\n//% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"compass\"\nint magneticForce(Dimension dimension) {\n if (!getWCompas()->magnetometer->isCalibrated())\n getWCompas()->magnetometer->calibrate();\n\n switch (dimension) {\n case Dimension::X:\n return getWCompas()->magnetometer->getX();\n case Dimension::Y:\n return getWCompas()->magnetometer->getY();\n case Dimension::Z:\n return getWCompas()->magnetometer->getZ();\n case Dimension::Strength:\n return getWCompas()->magnetometer->getFieldStrength();\n }\n return 0;\n}\n\n/**\n * Get the current compass heading in degrees.\n */\n//% help=input/compass-heading\n//% weight=56\n//% blockId=device_heading block=\"compass heading (°)\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"compass\"\nint compassHeading() {\n return getWCompas()->magnetometer->heading();\n}\n\n/**\n * Get the angular acceleration. This function is not supported in the simulator.\n * @param dimension TODO\n */\n//% help=input/gyroscopic-force weight=51\n//% blockId=device_get_gyroscopic_force block=\"angular acceleration|%NAME\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"gyroscope\"\nint gyroscopicForce(Dimension dimension) {\n switch (dimension) {\n case Dimension::X:\n return getWGyro()->gyroscope->getX();\n case Dimension::Y:\n return getWGyro()->gyroscope->getY();\n case Dimension::Z:\n return getWGyro()->gyroscope->getZ();\n case Dimension::Strength:\n return 0; // getWGyro()->gyroscope.getStrength();\n }\n return 0;\n}\n\n} // namespace input\n", "axis.h": "// Override in target to change inversion of axis\n\n#define ACC_SYSTEM SIMPLE_CARTESIAN\n#define ACC_UPSIDEDOWN true\n#define ACC_ROTATION COORDINATE_SPACE_ROTATED_180", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n }\n\n\n declare const enum Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n }\n\n\n declare const enum AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8,\n }\n\n\n declare const enum Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = 11, // ACCELEROMETER_EVT_SHAKE\n /**\n * Raised when the device tilts up\n */\n //% block=\"tilt up\"\n TiltUp = 1, // ACCELEROMETER_EVT_TILT_UP\n /**\n * Raised when the device tilts down\n */\n //% block=\"tilt down\"\n TiltDown = 2, // ACCELEROMETER_EVT_TILT_DOWN\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = 3, // ACCELEROMETER_EVT_TILT_LEFT\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = 4, // ACCELEROMETER_EVT_TILT_RIGHT\n /**\n * Raised when the screen faces up\n */\n //% block=\"face up\"\n FaceUp = 5, // ACCELEROMETER_EVT_FACE_UP\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"face down\"\n FaceDown = 6, // ACCELEROMETER_EVT_FACE_DOWN\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = 7, // ACCELEROMETER_EVT_FREEFALL\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = 8, // ACCELEROMETER_EVT_3G\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = 9, // ACCELEROMETER_EVT_6G\n /**\n * Raised when a 8G shock is detected\n */\n //% block=\"8g\"\n EightG = 10, // ACCELEROMETER_EVT_8G\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"accelerometer---lsm6dsl\",\n \"description\": \"The accelerometer library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"accelerometer.cpp\",\n \"target_accelerometer.h\",\n \"target_compass.h\",\n \"target_gyroscope.h\",\n \"axis.h\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"accelerometer---lsm6dsl\",\n \"description\": \"The accelerometer library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"accelerometer.cpp\",\n \"target_accelerometer.h\",\n \"target_compass.h\",\n \"target_gyroscope.h\",\n \"axis.h\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Do something when a gesture happens (like shaking the board).\n * @param gesture the type of gesture to track, eg: Gesture.Shake\n * @param body code to run when gesture is raised\n */\n //% help=input/on-gesture\n //% blockId=device_gesture_event block=\"on |%NAME\"\n //% parts=\"accelerometer\"\n //% gesture.fieldEditor=\"gridpicker\"\n //% gesture.fieldOptions.width=220\n //% gesture.fieldOptions.columns=3\n //% group=\"Movement\"\n //% weight=92 blockGap=12 shim=input::onGesture\n function onGesture(gesture: Gesture, body: () => void): void;\n\n /**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n * x=0, y=0 and z=-1023)\n * @param dimension TODO\n */\n //% help=input/acceleration\n //% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n //% parts=\"accelerometer\"\n //% dimension.fieldEditor=\"gridpicker\"\n //% dimension.fieldOptions.width=180\n //% dimension.fieldOptions.columns=2\n //% group=\"Movement\"\n //% weight=42 blockGap=8 shim=input::acceleration\n function acceleration(dimension: Dimension): int32;\n\n /**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n //% help=input/rotation\n //% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n //% parts=\"accelerometer\"\n //% group=\"Movement\"\n //% weight=38 shim=input::rotation\n function rotation(kind: Rotation): int32;\n\n /**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n //% help=input/set-accelerometer-range\n //% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n //% weight=5 advanced=true\n //% parts=\"accelerometer\"\n //% group=\"Movement\"\n //% weight=15 blockGap=8 shim=input::setAccelerometerRange\n function setAccelerometerRange(range: AcceleratorRange): void;\n\n /**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the\n * simulator.\n * @param dimension TODO\n */\n //% help=input/magnetic-force weight=51\n //% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"compass\" shim=input::magneticForce\n function magneticForce(dimension: Dimension): int32;\n\n /**\n * Get the current compass heading in degrees.\n */\n //% help=input/compass-heading\n //% weight=56\n //% blockId=device_heading block=\"compass heading (°)\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"compass\" shim=input::compassHeading\n function compassHeading(): int32;\n\n /**\n * Get the angular acceleration. This function is not supported in the simulator.\n * @param dimension TODO\n */\n //% help=input/gyroscopic-force weight=51\n //% blockId=device_get_gyroscopic_force block=\"angular acceleration|%NAME\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"gyroscope\" shim=input::gyroscopicForce\n function gyroscopicForce(dimension: Dimension): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_accelerometer.h": "#include \"LSM6DSL_Accelerometer.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\n\n// Wrapper classes\nclass WAccel {\n private:\n CODAL_I2C *i2c;\n codal::CoordinateSpace coordinateSpace;\n\n public:\n codal::Accelerometer *acc = nullptr;\n\n WAccel()\n : i2c(getI2C(LOOKUP_PIN(LSM6DSL_SDA), LOOKUP_PIN(LSM6DSL_SCL))),\n coordinateSpace(SIMPLE_CARTESIAN, true, COORDINATE_SPACE_ROTATED_180),\n acc(new codal::LSM6DSL_Accelerometer(i2c, 0xD4, coordinateSpace)) {}\n\n ~WAccel() { delete acc; }\n};\n} // namespace pxt", "target_compass.h": "#include \"LIS3MDL_Magnetometer.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\n\n// Wrapper classes\nclass WCompas {\n private:\n CODAL_I2C *i2c;\n codal::CoordinateSpace coordinateSpace;\n\n public:\n codal::Compass *magnetometer;\n\n WCompas()\n : i2c(getI2C(LOOKUP_PIN(LSM6DSL_SDA), LOOKUP_PIN(LSM6DSL_SCL))),\n coordinateSpace(codal::CoordinateSystem::SIMPLE_CARTESIAN),\n magnetometer(new codal::LIS3MDL_Magnetometer(i2c, 0x3C, coordinateSpace)) {\n magnetometer->configure();\n }\n\n ~WCompas() { delete magnetometer; }\n};\n} // namespace pxt", @@ -807,14 +808,14 @@ var pxtTargetBundle = { "barometer---lps22hb": { "barometer.cpp": "#include \"pxt.h\"\n#include \"target_barometer.h\"\n\nenum class PressureCondition {\n //% block=\"high\"\n High = SENSOR_THRESHOLD_HIGH,\n //% block=\"low\"\n Low = SENSOR_THRESHOLD_LOW\n};\n\nenum class PressureUnit {\n //% block=\"hPa\"\n HectoPascal,\n //% block=\"mBar\"\n mBar\n};\n\nnamespace pxt {\nSINGLETON(WBarometer);\n}\n\nnamespace input {\n\n/**\n * Run some code when the pressure changes from high to low, or from low to high.\n * @param condition the condition, low or high, the event triggers on\n * @param pressure the pressure at which this event happens, eg: 1013.25\n * @param unit the unit of the pressure\n */\n//% blockId=input_on_pressure_condition_changed block=\"on pressure %condition|at %pressure |%unit\"\n//% help=input/on-pressure-condition-changed blockExternalInputs=0\n//% parts=\"pressure\"\n//% group=\"Pressure\"\n//% weight=76\nvoid onPressureConditionChanged(PressureCondition condition, int pressure, PressureUnit unit, Action handler) {\n auto sensor = getWBarometer()->sensor;\n sensor->updateSample();\n\n float t = pressure;\n\n if (condition == PressureCondition::Low)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the pressure.\n */\n//% help=input/pressure\n//% blockId=device_pressure block=\"pressure in %unit\"\n//% parts=\"pressure\"\n//% group=\"Pressure\"\n//% weight=26\nint pressure(PressureUnit unit) {\n return (int)getWBarometer()->sensor->getValue();\n}\n} // namespace input", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum PressureCondition {\n //% block=\"high\"\n High = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"low\"\n Low = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum PressureUnit {\n //% block=\"hPa\"\n HectoPascal = 0,\n //% block=\"mBar\"\n mBar = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"barometer---lps22hb\",\n \"description\": \"A barometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"barometer.cpp\",\n \"target_barometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"barometer---lps22hb\",\n \"description\": \"A barometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"barometer.cpp\",\n \"target_barometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the pressure changes from high to low, or from low to high.\n * @param condition the condition, low or high, the event triggers on\n * @param pressure the pressure at which this event happens, eg: 1013.25\n * @param unit the unit of the pressure\n */\n //% blockId=input_on_pressure_condition_changed block=\"on pressure %condition|at %pressure |%unit\"\n //% help=input/on-pressure-condition-changed blockExternalInputs=0\n //% parts=\"pressure\"\n //% group=\"Pressure\"\n //% weight=76 shim=input::onPressureConditionChanged\n function onPressureConditionChanged(condition: PressureCondition, pressure: int32, unit: PressureUnit, handler: () => void): void;\n\n /**\n * Get the pressure.\n */\n //% help=input/pressure\n //% blockId=device_pressure block=\"pressure in %unit\"\n //% parts=\"pressure\"\n //% group=\"Pressure\"\n //% weight=26 shim=input::pressure\n function pressure(unit: PressureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_barometer.h": "#include \"LPS22HB_Pressure.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WBarometer {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::LPS22HB_Pressure *sensor;\n\n WBarometer()\n : i2c(getI2C(LOOKUP_PIN(LPS22HB_SDA), LOOKUP_PIN(LPS22HB_SCL))),\n sensor(new codal::LPS22HB_Pressure(DEVICE_ID_PRESSURE, i2c, 0xBA, 1023)) {}\n\n ~WBarometer() { delete sensor; }\n};\n} // namespace pxt" }, "distance---vl53l0x": { "distance.cpp": "#include \"pxt.h\"\n#include \"target_distance.h\"\n\nenum class DistanceCondition {\n //% block=\"far\"\n Far = SENSOR_THRESHOLD_HIGH,\n //% block=\"near\"\n Near = SENSOR_THRESHOLD_LOW\n};\n\nenum class DistanceUnit {\n //% block=\"mm\"\n Millimeter,\n //% block=\"cm\"\n Centimeter,\n //% block=\"dm\"\n Decimeter,\n //% block=\"m\"\n Meter\n};\n\nnamespace pxt {\nSINGLETON(WDistance);\n}\n\nnamespace input {\n\n/**\n * Run some code when the distance changes from near to far, or from far to near.\n * @param condition the condition, far or near, the event triggers on\n * @param distance the distance at which this event happens, eg: 15\n * @param unit the unit of the distance\n */\n//% blockId=input_on_distance_condition_changed block=\"on distance %condition|at %distance|%unit\"\n//% parts=\"distance\"\n//% help=input/on-distance-condition-changed blockExternalInputs=0\n//% group=\"Distance\" weight=76\nvoid onDistanceConditionChanged(DistanceCondition condition, int distance, DistanceUnit unit, Action handler) {\n auto sensor = getWDistance()->sensor;\n sensor->updateSample();\n\n int d;\n\n switch (unit) {\n case DistanceUnit::Millimeter:\n d = distance;\n break;\n case DistanceUnit::Centimeter:\n d = distance * 10;\n break;\n case DistanceUnit::Decimeter:\n d = distance * 100;\n break;\n case DistanceUnit::Meter:\n d = distance * 1000;\n break;\n default:\n d = 0;\n break;\n }\n\n if (condition == DistanceCondition::Near)\n sensor->setLowThreshold(d);\n else\n sensor->setHighThreshold(d);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the distance.\n */\n//% help=input/distance\n//% blockId=device_distance block=\"distance in %unit\"\n//% parts=\"distance\"\n//% group=\"Distance\"\n//% weight=26\nfloat distance(DistanceUnit unit) {\n int distance = getWDistance()->sensor->getValue();\n switch (unit) {\n case DistanceUnit::Millimeter:\n return distance;\n case DistanceUnit::Centimeter:\n return distance / 10.;\n case DistanceUnit::Decimeter:\n return distance / 100.;\n case DistanceUnit::Meter:\n return distance / 1000.;\n default:\n return 0;\n }\n}\n} // namespace input", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum DistanceCondition {\n //% block=\"far\"\n Far = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"near\"\n Near = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum DistanceUnit {\n //% block=\"mm\"\n Millimeter = 0,\n //% block=\"cm\"\n Centimeter = 1,\n //% block=\"dm\"\n Decimeter = 2,\n //% block=\"m\"\n Meter = 3,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"distance---vl53l0x\",\n \"description\": \"A distance sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"distance.cpp\",\n \"target_distance.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"distance---vl53l0x\",\n \"description\": \"A distance sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"distance.cpp\",\n \"target_distance.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the distance changes from near to far, or from far to near.\n * @param condition the condition, far or near, the event triggers on\n * @param distance the distance at which this event happens, eg: 15\n * @param unit the unit of the distance\n */\n //% blockId=input_on_distance_condition_changed block=\"on distance %condition|at %distance|%unit\"\n //% parts=\"distance\"\n //% help=input/on-distance-condition-changed blockExternalInputs=0\n //% group=\"Distance\" weight=76 shim=input::onDistanceConditionChanged\n function onDistanceConditionChanged(condition: DistanceCondition, distance: int32, unit: DistanceUnit, handler: () => void): void;\n\n /**\n * Get the distance.\n */\n //% help=input/distance\n //% blockId=device_distance block=\"distance in %unit\"\n //% parts=\"distance\"\n //% group=\"Distance\"\n //% weight=26 shim=input::distance\n function distance(unit: DistanceUnit): number;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_distance.h": "#include \"VL53L0X_Distance.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WDistance {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::VL53L0X_Distance *sensor;\n\n WDistance()\n : i2c(getI2C(LOOKUP_PIN(VL53L0X_SDA), LOOKUP_PIN(VL53L0X_SCL))),\n sensor(new codal::VL53L0X_Distance(DEVICE_ID_DISTANCE, i2c, LOOKUP_PIN(VL53L0X_SHUT), 0x52, 1023, 1000)) {\n\n // The VL53L0X need time to internally initialize, but when it is done, we can reduce the samplePerdiod\n sensor->setPeriod(100);\n }\n ~WDistance() { delete sensor; }\n};\n} // namespace pxt", "test.ts": "" @@ -822,7 +823,7 @@ var pxtTargetBundle = { "thermometer---hts221": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum TemperatureCondition {\n //% block=\"hot\"\n Hot = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"cold\"\n Cold = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum TemperatureUnit {\n //% block=\"°C\"\n Celsius = 0,\n //% block=\"°F\"\n Fahrenheit = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}", - "pxt.json": "{\n \"name\": \"thermometer---hts221\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"thermometer---hts221\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n //% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n //% parts=\"thermometer\"\n //% help=input/on-temperature-condition-changed blockExternalInputs=0\n //% group=\"Temperature\" weight=76 shim=input::onTemperatureConditionChanged\n function onTemperatureConditionChanged(condition: TemperatureCondition, temperature: int32, unit: TemperatureUnit, handler: () => void): void;\n\n /**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature in %unit\"\n //% parts=\"thermometer\"\n //% group=\"Temperature\"\n //% weight=26 shim=input::temperature\n function temperature(unit: TemperatureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_thermometer.h": "#include \"HTS221_Temperature.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WTemp {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::HTS221_Temperature *sensor;\n\n WTemp()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::HTS221_Temperature(DEVICE_ID_THERMOMETER, i2c, 0xBE, 1023)) {}\n ~WTemp() { delete sensor; }\n};\n} // namespace pxt\n", "thermometer.cpp": "#include \"pxt.h\"\n#include \"target_thermometer.h\"\n\nenum class TemperatureCondition {\n //% block=\"hot\"\n Hot = SENSOR_THRESHOLD_HIGH,\n //% block=\"cold\"\n Cold = SENSOR_THRESHOLD_LOW\n};\n\nenum class TemperatureUnit {\n //% block=\"°C\"\n Celsius,\n //% block=\"°F\"\n Fahrenheit\n};\n\nnamespace pxt {\nSINGLETON(WTemp);\n}\n\nnamespace input {\n\n/**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n//% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n//% parts=\"thermometer\"\n//% help=input/on-temperature-condition-changed blockExternalInputs=0\n//% group=\"Temperature\" weight=76\nvoid onTemperatureConditionChanged(TemperatureCondition condition, int temperature, TemperatureUnit unit, Action handler) {\n auto thermo = getWTemp();\n if (!thermo)\n return;\n\n auto sensor = thermo->sensor;\n sensor->updateSample();\n\n int t = unit == TemperatureUnit::Celsius ? temperature : ((temperature - 32) * 10) / 18;\n\n if (condition == TemperatureCondition::Cold)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n//% help=input/temperature\n//% blockId=device_temperature block=\"temperature in %unit\"\n//% parts=\"thermometer\"\n//% group=\"Temperature\"\n//% weight=26\nint temperature(TemperatureUnit unit) {\n auto thermo = getWTemp();\n\n // default to -1000 if not present\n int value = (NULL != thermo) ? (int)thermo->sensor->getValue() : -1000;\n\n if (unit == TemperatureUnit::Celsius)\n return value;\n else\n return (value * 18) / 10 + 32;\n}\n} // namespace input\n" @@ -830,7 +831,7 @@ var pxtTargetBundle = { "thermometer---lps22hb": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum TemperatureCondition {\n //% block=\"hot\"\n Hot = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"cold\"\n Cold = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum TemperatureUnit {\n //% block=\"°C\"\n Celsius = 0,\n //% block=\"°F\"\n Fahrenheit = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}", - "pxt.json": "{\n \"name\": \"thermometer---lps22hb\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"thermometer---lps22hb\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n //% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n //% parts=\"thermometer\"\n //% help=input/on-temperature-condition-changed blockExternalInputs=0\n //% group=\"Temperature\" weight=76 shim=input::onTemperatureConditionChanged\n function onTemperatureConditionChanged(condition: TemperatureCondition, temperature: int32, unit: TemperatureUnit, handler: () => void): void;\n\n /**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature in %unit\"\n //% parts=\"thermometer\"\n //% group=\"Temperature\"\n //% weight=26 shim=input::temperature\n function temperature(unit: TemperatureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_thermometer.h": "#include \"LPS22HB_Temperature.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WTemp {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::LPS22HB_Temperature *sensor;\n\n WTemp()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::LPS22HB_Temperature(DEVICE_ID_THERMOMETER, i2c, 0xBA, 1023)) {}\n ~WTemp() { delete sensor; }\n};\n} // namespace pxt\n", "thermometer.cpp": "#include \"pxt.h\"\n#include \"target_thermometer.h\"\n\nenum class TemperatureCondition {\n //% block=\"hot\"\n Hot = SENSOR_THRESHOLD_HIGH,\n //% block=\"cold\"\n Cold = SENSOR_THRESHOLD_LOW\n};\n\nenum class TemperatureUnit {\n //% block=\"°C\"\n Celsius,\n //% block=\"°F\"\n Fahrenheit\n};\n\nnamespace pxt {\nSINGLETON(WTemp);\n}\n\nnamespace input {\n\n/**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n//% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n//% parts=\"thermometer\"\n//% help=input/on-temperature-condition-changed blockExternalInputs=0\n//% group=\"Temperature\" weight=76\nvoid onTemperatureConditionChanged(TemperatureCondition condition, int temperature, TemperatureUnit unit, Action handler) {\n auto thermo = getWTemp();\n if (!thermo)\n return;\n\n auto sensor = thermo->sensor;\n sensor->updateSample();\n\n int t = unit == TemperatureUnit::Celsius ? temperature : ((temperature - 32) * 10) / 18;\n\n if (condition == TemperatureCondition::Cold)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n//% help=input/temperature\n//% blockId=device_temperature block=\"temperature in %unit\"\n//% parts=\"thermometer\"\n//% group=\"Temperature\"\n//% weight=26\nint temperature(TemperatureUnit unit) {\n auto thermo = getWTemp();\n\n // default to -1000 if not present\n int value = (NULL != thermo) ? (int)thermo->sensor->getValue() : -1000;\n\n if (unit == TemperatureUnit::Celsius)\n return value;\n else\n return (value * 18) / 10 + 32;\n}\n} // namespace input\n" @@ -838,7 +839,7 @@ var pxtTargetBundle = { "hygrometer---hts221": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum HumidityCondition {\n //% block=\"wet\"\n Wet = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"dry\"\n Dry = 1, // SENSOR_THRESHOLD_LOW\n }\n\n// Auto-generated. Do not edit. Really.\n", "hygrometer.cpp": "#include \"pxt.h\"\n#include \"target_hygrometer.h\"\n\nenum class HumidityCondition {\n //% block=\"wet\"\n Wet = SENSOR_THRESHOLD_HIGH,\n //% block=\"dry\"\n Dry = SENSOR_THRESHOLD_LOW\n};\n\nnamespace pxt {\nSINGLETON(WHygrometer);\n}\n\nnamespace input {\n\n/**\n * Run some code when the humidity changes from dry to wet, or from wet to dry.\n * @param condition the condition, wet or dry, the event triggers on\n * @param humidity the humidity at which this event happens, eg: 50\n * @param unit the unit of the humidity\n */\n//% blockId=input_on_humidity_condition_changed block=\"on humidity %condition|at %humidity percent\"\n//% help=input/on-humidity-condition-changed blockExternalInputs=0\n//% parts=\"humidity\"\n//% group=\"Humidity\" weight=76\nvoid onHumidityConditionChanged(HumidityCondition condition, int humidity, Action handler) {\n auto sensor = getWHygrometer()->sensor;\n sensor->updateSample();\n\n float t = humidity; //*10.;\n\n if (condition == HumidityCondition::Dry)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the relative humidity in percent.\n */\n//% help=input/humidity\n//% blockId=device_humidity block=\"relative humidity in percent\"\n//% parts=\"humidity\"\n//% group=\"Humidity\"\n//% weight=26\nint humidity() {\n return (int)getWHygrometer()->sensor->getValue(); /// 10.;\n}\n} // namespace input", - "pxt.json": "{\n \"name\": \"hygrometer---hts221\",\n \"description\": \"A hygrometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hygrometer.cpp\",\n \"target_hygrometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"hygrometer---hts221\",\n \"description\": \"A hygrometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hygrometer.cpp\",\n \"target_hygrometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the humidity changes from dry to wet, or from wet to dry.\n * @param condition the condition, wet or dry, the event triggers on\n * @param humidity the humidity at which this event happens, eg: 50\n * @param unit the unit of the humidity\n */\n //% blockId=input_on_humidity_condition_changed block=\"on humidity %condition|at %humidity percent\"\n //% help=input/on-humidity-condition-changed blockExternalInputs=0\n //% parts=\"humidity\"\n //% group=\"Humidity\" weight=76 shim=input::onHumidityConditionChanged\n function onHumidityConditionChanged(condition: HumidityCondition, humidity: int32, handler: () => void): void;\n\n /**\n * Get the relative humidity in percent.\n */\n //% help=input/humidity\n //% blockId=device_humidity block=\"relative humidity in percent\"\n //% parts=\"humidity\"\n //% group=\"Humidity\"\n //% weight=26 shim=input::humidity\n function humidity(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_hygrometer.h": "#include \"HTS221_Humidity.h\"\n#include \"Sensor.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WHygrometer {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::HTS221_Humidity *sensor;\n\n WHygrometer()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::HTS221_Humidity(DEVICE_ID_HUMIDITY, i2c, 0xBE, 1023)) {}\n\n ~WHygrometer() { delete sensor; }\n};\n} // namespace pxt" }, @@ -846,7 +847,7 @@ var pxtTargetBundle = { "SSD1306_128x64.svg": "\nimage/svg+xml\n\n\t\n\n\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\tVCC\n\n\tGND\n\n\tSCL\n\n\tSDA\n\n\t\n\t\n\t\n\t\n\t\n\tOLED 128x64 \n\n\tSSD1306 \n\n\tI2C\n\n\tblog.squix.ch\n\n", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum PixelColor {\n //% block=\"Black\"\n Black = 0,\n //% block=\"White\"\n White = 1,\n }\n\n\n declare const enum AddressScreen {\n //% block=\"0x78\"\n x74 = 0x78,\n //% block=\"0x7A\"\n x7A = 0x7A,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "//% color=\"#FF9933\" weight=50 icon=\"\\uf120\"\n//% groups='[\"Oled\", \"More\"]'\nnamespace oled {\n}\n", - "pxt.json": "{\n \"name\": \"oled\",\n \"description\": \"Support for OLED display based on the SSD1306\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"ns.ts\",\n \"screen.ts\",\n \"ssd1306.cpp\",\n \"target_ssd1306.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\",\n \"SSD1306_128x64.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"oled\",\n \"description\": \"Support for OLED display based on the SSD1306\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"ns.ts\",\n \"screen.ts\",\n \"ssd1306.cpp\",\n \"target_ssd1306.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\",\n \"SSD1306_128x64.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"ssd1306\": {\n \"simulationBehavior\": \"ssd1306\",\n \"visual\": {\n \"builtIn\": \"ssd1306\",\n \"width\": 171.054,\n \"height\": 170.167,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 62,\n \"y\": 10.167\n },\n {\n \"x\": 77,\n \"y\": 10.167\n },\n {\n \"x\": 92,\n \"y\": 10.167\n },\n {\n \"x\": 107,\n \"y\": 10.167\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"assembly\": [\n {\n \"pinIndices\": [\n 0,\n 1,\n 2,\n 3\n ]\n }\n ]\n }\n}", "screen.ts": "/**\n * Basic screen display functionalities\n */\n//% color=\"#FF9933\" weight=50 icon=\"\\uf120\"\n//% groups='[\"Oled\", \"More\"]'\nnamespace oled {\n const textOffset = 4;\n const lineOffset = 2;\n\n const screenHeight = 64;\n const screenWidth = 64;\n\n /**\n * Gets the text line height\n */\n export function lineHeight(): number {\n return 8\n }\n\n /**\n * Number of lines\n */\n export function lineCount(): number {\n return ((screenHeight - textOffset) / lineHeight()) >> 0\n }\n\n\n /**\n * Fill a rectangle with specific color\n * @param x x-coordinate in pixel of the upper left corner\n * @param y y-coordinate in pixel of the upper left corner\n * @param width width of the rectangle\n * @param height height of the rectangle\n * @param color filling color of the rectangle\n */\n //% group=\"More\" advanced=true\n //% help=screen/fillRect\n //% blockId=fill_rect_ssd1306 block=\"fill the rectangle at %x %y with %width %height in %color\"\n //% parts=\"ssd1306\"\n export function fillRect(x: number, y: number, width: number, height: number, color: PixelColor): void{\n\n }\n\n /**\n * Show text on the screen at a specific line.\n * @param text the text to print on the screen, eg: \"Hello world\"\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshowstring block=\"show string %text|at line %line\"\n //% weight=98 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-string\n export function showString(text: string, line: number) {\n // line indexing starts at 1.\n line = (line - 1) >> 0;\n const nlines = lineCount();\n if (line < 0 || line >= nlines) return; // out of screen\n \n const h = lineHeight();\n const y = textOffset + h * line;\n fillRect(0, y, screenWidth, h, PixelColor.Black); // clear background\n printString(text, PixelColor.White, 0, y)\n }\n\n /**\n * Shows a number on the screen\n * @param value the numeric value\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshownumber block=\"show number %name|at line %line\"\n //% weight=96 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-number\n //% line.min=1 line.max=10\n export function showNumber(value: number, line: number) {\n showString(\"\" + value, line);\n }\n\n /**\n * Shows a name, value pair on the screen\n * @param value the numeric value\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshowvalue block=\"show value %name|: %text|at line %line\"\n //% weight=94 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-value\n //% line.min=1 line.max=10\n export function showValue(name: string, value: number, line: number) {\n value = Math.round(value * 1000) / 1000;\n showString((name ? name + \": \" : \"\") + value, line);\n }\n\n /**\n * Clear the screen\n */\n //% blockId=displayclear block=\"clear display\"\n //% weight=90\n //% group=\"Screen\"\n //% help=display/clear\n export function clear() {\n fillScreen(PixelColor.Black)\n }\n\n}\n\n\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace oled {\n\n /**\n * @brief Initialized screen\n *\n */\n //% group=\"More\" advanced=true\n //% help=screen/ssd1306_init_screen\n //% blockId=ssd1306_init_screen block=\"Initialized screen on address %address, with width %width and height %height\"\n //% parts=\"ssd1306\" weight=95 address.defl=0x74 width.defl=128 height.defl=64 shim=oled::initScreen\n function initScreen(address?: AddressScreen, width?: uint16, height?: uint16): void;\n\n /**\n * @brief Print string on screen at the given position\n *\n * @param x pixel coordinate on X axis\n * @param y pixel coordinate on Y axis\n * @param str the string to print\n * @param color the color use to print on screen\n */\n //% group=\"More\" advanced=true\n //% help=screen/printString\n //% blockId=print_string_ssd1306 block=\"print %str on screen in %color at x: %x|y: %y\"\n //% parts=\"ssd1306\" shim=oled::printString\n function printString(str: string, color: PixelColor, x: uint8, y: uint8): void;\n\n /**\n * @brief Fill the screen with specific color\n *\n * @param color the color use to fill the screen\n */\n //% group=\"More\" advanced=true\n //% help=screen/fillScreen\n //% blockId=fill_screen_ssd1306 block=\"fill the screen in %color\"\n //% parts=\"ssd1306\" shim=oled::fillScreen\n function fillScreen(color: PixelColor): void;\n\n /**\n * @brief set the color of a specific pixel\n *\n * @param x the coordinate pixel on X axis\n * @param y the coordinate pixel on Y axis\n * @param color the color of the pixel\n */\n //% group=\"More\" advanced=true\n //% help=screen/setPixel\n //% blockId=set_pixel_ssd1306 block=\"set pixel at %x, %y to %color\"\n //% parts=\"ssd1306\" shim=oled::setPixel\n function setPixel(x: uint8, y: uint8, color: PixelColor): void;\n\n /**\n * @brief Define if the screen should be inverted\n *\n * @param invert if True the screen is inverted, otherwise False\n */\n //% group=\"More\" advanced=true\n //% help=screen/invertScreen\n //% blockId=invert_screen_ssd1306 block=\"invert the screen : %invert\"\n //% parts=\"ssd1306\" shim=oled::invertScreen\n function invertScreen(invert: boolean): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -855,7 +856,7 @@ var pxtTargetBundle = { }, "wifi": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum HttpMethod {\n //%\n GET = 0,\n //%\n POST = 1,\n //%\n PUT = 2,\n //%\n HEAD = 3,\n //%\n DELETE = 4,\n //%\n PATCH = 5,\n //%\n OPTIONS = 6,\n //%\n CONNECT = 7,\n //%\n TRACE = 8,\n }\ndeclare namespace wifi {\n}\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"wifi\",\n \"description\": \"Wifi support for the module ISM43362-M3G-L44\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"wifi.ts\",\n \"wifi.cpp\",\n \"target_wifi.h\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"wifi\",\n \"description\": \"Wifi support for the module ISM43362-M3G-L44\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"wifi.ts\",\n \"wifi.cpp\",\n \"target_wifi.h\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Support for additional wifi services.\n */\n //%weight=40 icon=\"\\uf1eb\"\ndeclare namespace wifi {\n\n /**\n * @brief Execute HTTP method.\n * @param method HTTP method, eg: HttpMethod.GET\n * @param host Host, eg: \"google.com\"\n * @param port Port, eg: 80\n * @param urlPath Path, eg: \"/search?q=something\"\n * @param headers Headers\n * @param body Body\n */\n //% blockId=wifi_execute_http_method blockHidden=1 shim=wifi::executeHttpMethod\n function executeHttpMethod(method: HttpMethod, host: string, port: int32, urlPath: string, headers: string, body: string, time: int32): void;\n\n /**\n * Used internally by the library.\n */\n //% shim=wifi::onReceivedData\n function onReceivedData(handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_wifi.h": "#include \"pxt.h\"\n#include \"ISM43362_M3G_L44_driver.h\"\n\nnamespace pxt {\nclass WWifi {\n private:\n CODAL_SPI *spi;\n\n public:\n IsmDrvClass wifi;\n uint8_t wifi_status = WL_IDLE_STATUS;\n\n WWifi()\n : spi(pxt::getSPI(LOOKUP_PIN(WIFI_ISM43362_MOSI), LOOKUP_PIN(WIFI_ISM43362_MISO), LOOKUP_PIN(WIFI_ISM43362_SCK))),\n wifi(spi, LOOKUP_PIN(WIFI_ISM43362_CS), LOOKUP_PIN(WIFI_ISM43362_COMMAND_DATA_READY), LOOKUP_PIN(WIFI_ISM43362_RESET),\n LOOKUP_PIN(WIFI_ISM43362_WAKE_UP)) {}\n};\n} // namespace pxt", "wifi.cpp": "#include \"pxt.h\"\n#include \"target_wifi.h\"\n\n#define DEVICE_ID_WIFI_ISM43362_DATA_READY 2510\n#define WIFI_ISM43362_EVT_DATA_READY 1\n\nenum class HttpMethod {\n //%\n GET,\n //%\n POST,\n //%\n PUT,\n //%\n HEAD,\n //%\n DELETE,\n //%\n PATCH,\n //%\n OPTIONS,\n //%\n CONNECT,\n //%\n TRACE\n};\n\nnamespace pxt {\nSINGLETON(WWifi);\n}\n\nuint8_t _sock;\n\n/**\n * Support for additional wifi services.\n */\n//%weight=40 icon=\"\\uf1eb\"\nnamespace wifi {\n\nint networksVisible() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n wifi.ES_WIFI_ListAccessPoints();\n return wifi.ES_WIFI_GetApNbr();\n}\n\nvoid attach(String ssid, String passphrase) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n uint8_t &wifi_status = getWWifi()->wifi_status;\n\n if (wifi.ES_WIFI_Connect(ssid->getUTF8Data(), passphrase->getUTF8Data(), ES_WIFI_SEC_WPA_WPA2) == ES_WIFI_STATUS_OK) {\n wifi_status = WL_CONNECTED;\n } else {\n wifi.ES_WIFI_Disconnect();\n wifi_status = WL_CONNECT_FAILED;\n }\n}\n\nbool isAttached() {\n uint8_t &wifi_status = getWWifi()->wifi_status;\n return wifi_status == WL_CONNECTED;\n}\n\nvoid detach() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n uint8_t &wifi_status = getWWifi()->wifi_status;\n if (wifi_status != WL_NO_SHIELD) {\n wifi.ES_WIFI_Disconnect();\n wifi_status = WL_DISCONNECTED;\n }\n}\n\n/**\n * @brief Start building up a packet to send to the remote host\n * @param ip : IP to which to send the packet\n * @param port : port to which to send the packet\n * @retval 1 if successful, 0 if there was a problem with the supplied IP address or port\n */\nint connect(IPAddress ip, uint16_t port) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n int8_t sock;\n if (_sock == NO_SOCKET_AVAIL) {\n sock = wifi.getFreeSocket(); // get next free socket\n if (sock != -1) {\n _sock = sock;\n }\n }\n if (_sock != NO_SOCKET_AVAIL) {\n // set connection parameter and start client\n wifi.ES_WIFI_SetConnectionParam(_sock, ES_WIFI_TCP_CONNECTION, port, ip);\n wifi.ES_WIFI_StartClientConnection(_sock);\n return 1;\n }\n return 0;\n}\n\n/**\n * @brief Start building up a packet to send to the remote host\n * @param host : host to which to send the packet\n * @param port : port to which to send the packet\n * @retval 1 if successful, 0 if there was a problem with the supplied IP address or port\n */\nint connect(String host, uint16_t port) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n IPAddress remote_addr; // IP address of the host\n\n wifi.ES_WIFI_DNS_LookUp(host->getUTF8Data(), &remote_addr);\n return connect(remote_addr, port);\n}\n\n/**\n * @brief Get socket state\n @param None\n * @retval socket state\n */\nuint8_t status() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n if (_sock == 255) {\n return SOCKET_FREE;\n } else {\n return wifi.getSocketState(_sock);\n }\n}\n\n/**\n * @brief Get connection state\n @param None\n * @retval Socket state, FREE or BUSY\n */\nuint8_t connected() {\n if (_sock == 255) {\n return 0;\n } else {\n return status();\n }\n}\n\n/**\n * @brief Close the client connection\n * @param None\n * @retval None\n */\nvoid stop() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n if (_sock == NO_SOCKET_AVAIL) {\n return;\n }\n wifi.ES_WIFI_StopServerSingleConn(_sock);\n _sock = NO_SOCKET_AVAIL;\n}\n\n/**\n * @brief Read up to size bytes from the current packet and place them into buffer\n * @param buffer : Where to place read data\n * @param size : length of data to read\n * @retval Returns the number of bytes read, or 0 if none are available\n */\nint read(char *buf, size_t size) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n uint16_t receivedLength = 0; // number of data received\n\n wifi.ES_WIFI_ReceiveData(_sock, (uint8_t *)buf, size, &receivedLength, WIFI_TIMEOUT);\n if (receivedLength < size) {\n buf[receivedLength] = '\\0'; // string end\n }\n return receivedLength;\n}\n\n/**\n * @brief Write size bytes from buffer into the packet\n * @param buf : data to write\n * @param size : size of data to write\n * @retval size of write data\n */\nsize_t write(const char *buf, size_t size) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n uint16_t sentLength = 0; // number of data really send\n uint8_t *temp = (uint8_t *)buf;\n\n wifi.ES_WIFI_SendResp(_sock, temp, size, &sentLength, WIFI_TIMEOUT);\n return sentLength;\n}\n\nString getHttpMethodString(HttpMethod method) {\n switch (method) {\n case HttpMethod::GET:\n return String(\"GET\");\n case HttpMethod::POST:\n return String(\"POST\");\n default:\n return String();\n }\n}\n\n/**\n * @brief Execute HTTP method.\n * @param method HTTP method, eg: HttpMethod.GET\n * @param host Host, eg: \"google.com\"\n * @param port Port, eg: 80\n * @param urlPath Path, eg: \"/search?q=something\"\n * @param headers Headers\n * @param body Body\n */\n//% blockId=wifi_execute_http_method blockHidden=1\nvoid executeHttpMethod(HttpMethod method, String host, int port, String urlPath, String headers, String body, int time) {\n String methodName = getHttpMethodString(method);\n\n if (connect(host, 80)) {\n write(methodName->getUTF8Data(), methodName->getUTF8Size());\n write(\" \", 1);\n write(host->getUTF8Data(), host->getUTF8Size());\n write(\" HTTP/1.1\\r\\n\", 11);\n\n write(\"Host: \", 6);\n write(host->getUTF8Data(), host->getUTF8Size());\n write(\"\\r\\n\", 2);\n\n write(\"Connection: Close\\r\\n\", 19);\n\n if (headers->getLength() > 0) {\n write(headers->getUTF8Data(), headers->getUTF8Size());\n }\n if (body->getLength() > 0) {\n write(\"\\r\\n\", 2);\n write(body->getUTF8Data(), body->getUTF8Size());\n }\n write(\"\\r\\n\", 2);\n }\n}\n\n/**\n * Used internally by the library.\n */\n//%\nvoid onReceivedData(Action handler) {\n registerWithDal(DEVICE_ID_WIFI_ISM43362_DATA_READY, WIFI_ISM43362_EVT_DATA_READY, handler);\n}\n\n} // namespace wifi", @@ -864,19 +865,19 @@ var pxtTargetBundle = { "magnetics": { "enums.d.ts": "", "ns.ts": "\n//% color=\"#B4009E\" weight=40 icon=\"\\uf076\"\nnamespace magnetics {\n}", - "pxt.json": "{\n \"name\": \"magnetics\",\n \"description\": \"Radio service for mesh networking\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"radioBLE.cpp\",\n \"target_radioBLE.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"magnetics\",\n \"description\": \"Radio service for mesh networking\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"radioBLE.cpp\",\n \"target_radioBLE.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "radioBLE.cpp": "#include \"pxt.h\"\n#include \"target_radioBLE.h\"\n#include \"HCI_SPI.h\"\n#include \"BLERemoteDevice.h\"\n\n#include \n\n// CODAL_SPI spiBLE(*LOOKUP_PIN(BLE_SPI_MISO), *LOOKUP_PIN(BLE_SPI_MOSI), *LOOKUP_PIN(BLE_SPI_SCLK));\nCODAL_SPI spiBLE(*lookupPin(43), *lookupPin(44), *lookupPin(42));\nHCI_SPI *hci = new HCI_SPI(spiBLE, *lookupPin(61U), *lookupPin(70U), *lookupPin(8U));\n\nchar stringBuffer[32] = {0};\n\nnamespace pxt {\nSINGLETON(WRadioBLE);\n\nvoid WRadioBLE::configure() {\n if (isConfigured) {\n return;\n }\n\n ble = new BLEDevice_Component(12345, hci);\n ble->init();\n\n isConfigured = true;\n}\n\n} // namespace pxt\n\nnamespace magnetics {\nString get_safe_string(std::vector &data) {\n\n std::string result = \"\";\n\n for (auto c : data) {\n if (c >= 32 && c <= 126) {\n result += (char)c;\n }\n }\n\n return mkString(result.c_str(), result.size());\n}\n\n/**\n * Start the device to sending data (by default the sending is activated)\n *\n */\n//% blockId=ble_start_emitting block=\"Start Send mode\"\n//% help=magnetics/ble_start_emitting weight=95\nvoid startEmitting() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->startAdvertising();\n radio->isAdvertisingStarted = true;\n}\n\n/**\n * Stop the device to sending data\n *\n */\n//% blockId=ble_stop_emitting block=\"Stop Send mode\"\n//% help=magnetics/ble_stop_emitting weight=95\nvoid stopEmitting() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->stopAdvertising();\n radio->isAdvertisingStarted = false;\n}\n\n/**\n * Start the device to receiving data (by default the receiving is activated)\n *\n */\n//% blockId=ble_start_scanning block=\"Start Scan mode\"\n//% help=magnetics/ble_start_scanning weight=91\nvoid startScanning() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->startScanning();\n radio->isScanningStarted = true;\n}\n\n/**\n * Stop the device to receiving data\n *\n */\n//% blockId=ble_stop_scanning block=\"Stop Scan mode\"\n//% help=magnetics/ble_stop_scanning weight=91\nvoid stopScanning() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->stopScanning();\n radio->isScanningStarted = false;\n}\n\n/**\n * Set the BLE device local name\n *\n * @param name The name\n */\n//% blockId=ble_set_local_name block=\"BLE device name : %name\"\n//% help=magnetics/ble_set_local_name weight=90\nvoid setLocalName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->advData.setLocalName(name->getUTF8Data());\n radio->ble->setAdvertisingData(radio->advData);\n}\n\n/**\n * Send string data\n *\n */\n//% blockId=ble_set_string_data block=\"BLE send string %data\"\n//% help=magnetics/ble_set_string_data weight=71\nvoid setAdvertisingStringData(String data) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->scanData.setUserData(data->getUTF8Data());\n radio->ble->setScanResponseData(radio->scanData);\n}\n\n/**\n * Send \"key:value\" data\n *\n */\n//% blockId=ble_set_keyvalue_data block=\"BLE send key %key: value %value\"\n//% help=magnetics/ble_set_keyvalue_data weight=70\nvoid setAdvertisingKeyValueData(String key, float value) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n int32_t intPart = (int32_t)value;\n int8_t fracPart = ((int32_t)value * 100) - (intPart * 100);\n int size = sprintf(stringBuffer, \"%s:%d.%d\", key->getUTF8Data(), intPart, fracPart);\n\n if (size < 0) {\n setAdvertisingStringData(mkString(\"ERROR. KEY/VALUE\", 16));\n } else {\n setAdvertisingStringData(mkString(stringBuffer, size));\n }\n}\n\n/**\n * Is there any data from a device with specific name ?\n *\n */\n//% blockId=ble_available_data_from_name block=\"is available BLE data from %name\"\n//% help=magnetics/ble_available_data_from_name weight=65\nbool availableDataFromName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n return radio->ble->availableScan(name->getUTF8Data()) > 0;\n}\n\n/**\n * Get the data from the device with a specific name (if there are multiple device with the same name, the first who emit will\n * be use)\n *\n */\n//% blockId=ble_receive_data_from_name block=\"BLE receive data from %name\"\n//% help=magnetics/ble_receive_data_from_name weight=65\nString readDataFromName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n std::vector result = radio->ble->getScanResult(name->getUTF8Data());\n\n if (result.size() > 0) {\n auto firstDevice = result[0];\n auto servicesDatas = firstDevice.getAllServiceDatas();\n\n if (servicesDatas.size() > 0) {\n return get_safe_string(servicesDatas[0].data);\n }\n }\n return mkString(\"\", 0);\n}\n\n/**\n * Run some code when we receive new message from device\n */\n//% blockId=ble_on_new_message block=\"on new message from %name\"\n//% help=magnetics/ble_on_new_message weight=60\nvoid onNewMessageReceived(String name, Action handler) {}\n\n} // namespace magnetics\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace magnetics {\n\n /**\n * Start the device to sending data (by default the sending is activated)\n *\n */\n //% blockId=ble_start_emitting block=\"Start Send mode\"\n //% help=magnetics/ble_start_emitting weight=95 shim=magnetics::startEmitting\n function startEmitting(): void;\n\n /**\n * Stop the device to sending data\n *\n */\n //% blockId=ble_stop_emitting block=\"Stop Send mode\"\n //% help=magnetics/ble_stop_emitting weight=95 shim=magnetics::stopEmitting\n function stopEmitting(): void;\n\n /**\n * Start the device to receiving data (by default the receiving is activated)\n *\n */\n //% blockId=ble_start_scanning block=\"Start Scan mode\"\n //% help=magnetics/ble_start_scanning weight=91 shim=magnetics::startScanning\n function startScanning(): void;\n\n /**\n * Stop the device to receiving data\n *\n */\n //% blockId=ble_stop_scanning block=\"Stop Scan mode\"\n //% help=magnetics/ble_stop_scanning weight=91 shim=magnetics::stopScanning\n function stopScanning(): void;\n\n /**\n * Set the BLE device local name\n *\n * @param name The name\n */\n //% blockId=ble_set_local_name block=\"BLE device name : %name\"\n //% help=magnetics/ble_set_local_name weight=90 shim=magnetics::setLocalName\n function setLocalName(name: string): void;\n\n /**\n * Send string data\n *\n */\n //% blockId=ble_set_string_data block=\"BLE send string %data\"\n //% help=magnetics/ble_set_string_data weight=71 shim=magnetics::setAdvertisingStringData\n function setAdvertisingStringData(data: string): void;\n\n /**\n * Send \"key:value\" data\n *\n */\n //% blockId=ble_set_keyvalue_data block=\"BLE send key %key: value %value\"\n //% help=magnetics/ble_set_keyvalue_data weight=70 shim=magnetics::setAdvertisingKeyValueData\n function setAdvertisingKeyValueData(key: string, value: number): void;\n\n /**\n * Is there any data from a device with specific name ?\n *\n */\n //% blockId=ble_available_data_from_name block=\"is available BLE data from %name\"\n //% help=magnetics/ble_available_data_from_name weight=65 shim=magnetics::availableDataFromName\n function availableDataFromName(name: string): boolean;\n\n /**\n * Get the data from the device with a specific name (if there are multiple device with the same name, the first who emit will\n * be use)\n *\n */\n //% blockId=ble_receive_data_from_name block=\"BLE receive data from %name\"\n //% help=magnetics/ble_receive_data_from_name weight=65 shim=magnetics::readDataFromName\n function readDataFromName(name: string): string;\n\n /**\n * Run some code when we receive new message from device\n */\n //% blockId=ble_on_new_message block=\"on new message from %name\"\n //% help=magnetics/ble_on_new_message weight=60 shim=magnetics::onNewMessageReceived\n function onNewMessageReceived(name: string, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_radioBLE.h": "#pragma once\n\n#include \"pxt.h\"\n\n#include \"BLEDevice_Component.h\"\n#include \"AdvertisingData.h\"\n#include \"AdvertisingFlagsBuilder.h\"\n\nnamespace pxt {\nclass WRadioBLE {\n private:\n public:\n codal::BLEDevice_Component *ble;\n AdvertisingData advData;\n AdvertisingData scanData;\n bool isAdvertisingStarted;\n bool isScanningStarted;\n\n WRadioBLE() : ble(nullptr), isAdvertisingStarted(false), isScanningStarted(false), isConfigured(false) {\n advData.setFlags(AdvertisingFlagsBuilder().addBrEdrNotSupported().addLeGeneralDiscoverableMode().build());\n }\n\n void configure();\n\n private:\n bool isConfigured;\n};\n} // namespace pxt\n" }, "datalogger": { "datalogger.ts": "/**\n * A tiny data logging framework\n */\n//% weight=80 color=#00a0a0 icon=\"\" blockGap=8\n//% groups='[\"Data\", \"Configuration\"]'\nnamespace datalogger {\n\n let separator = ',';\n let _headers: string[] = undefined;\n let _headersWritten: boolean = false;\n let _row: number[] = undefined;\n let _samples: number[] = undefined;\n let _start: number;\n let _enabled = true;\n let _samplingInterval = -1;\n let _lastSampleTime = -1;\n let _console = false;\n\n function clear() {\n _headers = undefined;\n _row = undefined;\n }\n\n function sendHeaders(){\n const line = _headers.join(separator);\n Serial.writeLine(`sep=${separator}`);\n Serial.writeLine(line);\n }\n\n function sendRow(){\n const line = _row.join(separator);\n Serial.writeLine(line);\n }\n\n function initRow() {\n if (_row) return;\n\n if (!_headers) {\n _headers = [];\n _headersWritten = false;\n _start = control.millis();\n }\n _row = [];\n _samples = [];\n _lastSampleTime = control.millis();\n const s = (_lastSampleTime - _start) / 1000;\n addValue(\"time\", s);\n }\n\n function commitRow() {\n // write row if any data\n if (_row && _row.length > 0) {\n \n // write headers for the first row\n if (!_headersWritten) {\n sendHeaders();\n if (_console){\n console.log(_headers.slice(1).join(separator));\n }\n _headersWritten = true;\n }\n\n // commit row data\n if (_samplingInterval <= 0 || control.millis() - _lastSampleTime >= _samplingInterval) {\n\n // average data\n for(let i = 1; i < _row.length; ++i) {\n _row[i] /= _samples[i];\n }\n\n // append row\n sendRow();\n\n if (_console) {\n // drop time\n console.log(_row.slice(1).join(separator));\n }\n\n // clear values\n _row = undefined;\n _lastSampleTime = -1;\n }\n }\n }\n\n /**\n * Start a new row of data\n */\n //% group=\"Data\"\n //% weight=100\n //% blockId=datalogAddRow block=\"data logger add row\"\n //% help=datalogger/add-row\n export function addRow(): void {\n if (!_enabled) return;\n\n commitRow();\n initRow();\n }\n\n /**\n * Add a named value to the row of data\n * @param name name of the cell, eg: \"x\"\n * @param value value of the cell, eg: 0\n */\n //% group=\"Data\"\n //% weight=99\n //% blockId=datalogAddValue block=\"data logger add %name|=%value\"\n //% blockGap=12\n //% help=datalogger/add-value\n export function addValue(name: string, value: number) {\n if (!_row) return;\n\n let idx = -1;\n\n // happy path\n if (_headers[_row.length] === name)\n idx = _row.length;\n else {\n idx = _headers.indexOf(name);\n if (idx < 0) {\n _headers.push(name);\n idx = _headers.length - 1;\n }\n }\n\n if( _row[idx] == undefined ){\n _row[idx] = value;\n _samples[idx] = 1;\n }\n else{\n _row[idx] += value;\n _samples[idx] += 1;\n }\n }\n\n /**\n * Commits any buffered row to disk\n */\n //%\n export function flush() {\n }\n\n /**\n * Set the minimum number of milliseconds between rows\n * @param millis milliseconds between each sample, eg: 50\n */\n //% group=\"Configuration\"\n //% blockId=datalogSetSamplingInterval block=\"set data logger sampling interval to $millis|(ms)\"\n //% millis.shadow=timePicker\n //% help=datalogger/set-sample-interval\n export function setSampleInterval(millis: number) {\n _samplingInterval = millis >> 0;\n }\n\n /**\n * Turn on or off datalogging\n * @param enabled \n */\n //% group=\"Configuration\"\n //% blockId=datalogEnabled block=\"data logger $enabled\"\n //% enabled.shadow=toggleOnOff\n //% help=datalogger/set-enabled\n export function setEnabled(enabled: boolean) {\n flush();\n _enabled = enabled;\n }\n\n /**\n * Send the data logger output to the console\n * @param enabled \n */\n //% group=\"Configuration\"\n //% blockId=\"datalogConsole\" block=\"data logger to console $enabled\"\n //% enabled.shadow=toggleOnOff\n //% help=datalogger/send-to-console\n export function sendToConsole(enabled: boolean) {\n _console = enabled;\n }\n}\n", - "pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Tiny data serial logging framework\",\n \"dependencies\": {\n \"core\": \"*\",\n \"serial\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n" + "pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Tiny data serial logging framework\",\n \"dependencies\": {\n \"core\": \"*\",\n \"serial\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n" }, "hcsr04": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum MHCSR04Unit {\n //% block=\"m\"\n M = 0,\n //% block=\"dm\"\n Dm = 1,\n //% block=\"cm\"\n Cm = 2,\n //% block=\"mm\"\n Mm = 3,\n }\n\n\n declare const enum MDistanceBehold {\n //% block=\"Near\"\n Near = 0,\n //% block=\"Far\"\n Far = 1,\n }\ndeclare namespace HCSR04 {\n}\n\n// Auto-generated. Do not edit. Really.\n", "hcsr04.cpp": "#include \"pxt.h\"\n#include \"target_hcsr04.h\"\n\nenum class MHCSR04Unit {\n //% block=\"m\"\n M = 0, \n //% block=\"dm\"\n Dm = 1, \n //% block=\"cm\"\n Cm = 2, \n //% block=\"mm\"\n Mm = 3\n};\n\nenum class MDistanceBehold {\n //% block=\"Near\"\n Near = 0, \n //% block=\"Far\"\n Far = 1\n};\n\n\nnamespace pxt {\n SINGLETON(WHCSR04);\n}\n\n//% color=\"#456F93\" icon=\"\\uf028\" blockGap=8\nnamespace HCSR04 {\n \n/**\n * @brief Get the value of the sensor \n *\n * @param unit the unit of the distance\n * @return uint16_t\n */\n//% block=\"get distance in %unit\"\n//% blockId=\"hcsr04_get_distance\"\n//% group=\"HCSR04\" weight=76\n//% parts=\"hcsr04\"\nuint16_t getDistance(MHCSR04Unit unit) {\n return getWHCSR04()->hcsr04->getDistance(static_cast(unit));\n}\n\nvoid callActionNear() {\n runInParallel(getWHCSR04()->actNear);\n}\n\nvoid callActionFar() {\n runInParallel(getWHCSR04()->actFar);\n}\n\n/**\n * @brief Creates a new event that triggers when the sensor is near or far of the distance\n *\n * @param fromDistanceIs the direction that triggers the event\n * @param distance the value \n * @param unit the unit of the distance\n * @param handler what the event does\n */\n//% block=\"on distance %fromDistanceIs from %distance %unit\"\n//% blockId=\"hcsr04_register_distance_event\"\n//% group=\"HCSR04\" weight=67\n//% parts=\"hcsr04\"\nvoid onDistanceFrom(MDistanceBehold fromDistanceIs, uint16_t distance, MHCSR04Unit unit, Action handler) {\n switch (fromDistanceIs)\n {\n case MDistanceBehold::Near : \n getWHCSR04()->actNear = handler;\n getWHCSR04()->hcsr04->registerDistanceEvent(static_cast(fromDistanceIs), distance, static_cast(unit), callActionNear);\n break;\n case MDistanceBehold::Far : \n getWHCSR04()->actFar = handler;\n getWHCSR04()->hcsr04->registerDistanceEvent(static_cast(fromDistanceIs), distance, static_cast(unit), callActionFar);\n break;\n default:\n break;\n }\n}\n \n} // namespace HCSR04\n", - "pxt.json": "{\n \"name\": \"hcsr04\",\n \"description\": \"Library for the HC-SR04 sensor\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hcsr04.cpp\",\n \"target_hcsr04.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"hcsr04\",\n \"description\": \"Library for the HC-SR04 sensor\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hcsr04.cpp\",\n \"target_hcsr04.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"hcsr04\": {\n \"simulationBehavior\": \"hcsr04\",\n \"visual\": {\n \"builtIn\": \"hcsr04\",\n \"width\": 250,\n \"height\": 116.3769,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 110,\n \"y\": 10\n },\n {\n \"x\": 121,\n \"y\": 10\n },\n {\n \"x\": 132,\n \"y\": 10\n },\n {\n \"x\": 143,\n \"y\": 10\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"fiveVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"D6\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"D7\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"assembly\": [\n {\n \"pinIndices\": [0, 1, 2, 3]\n }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% color=\"#456F93\" icon=\"\\uf028\" blockGap=8\ndeclare namespace HCSR04 {\n\n /**\n * @brief Get the value of the sensor \n *\n * @param unit the unit of the distance\n * @return uint16_t\n */\n //% block=\"get distance in %unit\"\n //% blockId=\"hcsr04_get_distance\"\n //% group=\"HCSR04\" weight=76\n //% parts=\"hcsr04\" shim=HCSR04::getDistance\n function getDistance(unit: MHCSR04Unit): uint16;\n\n /**\n * @brief Creates a new event that triggers when the sensor is near or far of the distance\n *\n * @param fromDistanceIs the direction that triggers the event\n * @param distance the value \n * @param unit the unit of the distance\n * @param handler what the event does\n */\n //% block=\"on distance %fromDistanceIs from %distance %unit\"\n //% blockId=\"hcsr04_register_distance_event\"\n //% group=\"HCSR04\" weight=67\n //% parts=\"hcsr04\" shim=HCSR04::onDistanceFrom\n function onDistanceFrom(fromDistanceIs: MDistanceBehold, distance: uint16, unit: MHCSR04Unit, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_hcsr04.h": "#include \"HCSR04Sensor.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WHCSR04 {\n public:\n codal::HCSR04Sensor *hcsr04;\n Action actNear;\n Action actFar;\n\n WHCSR04() { \n hcsr04 = new codal::HCSR04Sensor(*LOOKUP_PIN(D6), *LOOKUP_PIN(D7), 1337);\n }\n};\n} // namespace pxt\n" @@ -885,7 +886,7 @@ var pxtTargetBundle = { "README.md": "# lcd\n\nPorted from STM32 lcd Support.\n", "lcd_i2c.cpp": "#include \"pxt.h\"\n#include \"target_lcd_i2c.h\"\n\nnamespace pxt {\nSINGLETON(WLCDI2C);\n}\n\nnamespace lcd_i2c {\nuint8_t strAddressToNumber(String addr) {\n uint8_t result = 0;\n\n for (uint8_t i = 0; i < 2 && i < addr->getLength(); i++) {\n char c = *(addr->getUTF8DataAt(i));\n\n if (c >= '0' && c <= '9') {\n result += c - '0';\n } else if (c >= 'A' && c <= 'F') {\n result += 10 + (c - 'A');\n } else if (c >= 'a' && c <= 'f') {\n result += 10 + (c - 'a');\n } else {\n return 0;\n }\n }\n\n return result;\n}\n\n/**\n * @brief Initialise the 16x2 screen with address 0x4E\n */\n//% blockId=\"I2C_LCD_INIT\"\n//% block=\"init i2c LCD\"\n//% weight=100\n//% blockGap=8\n//% parts=lcd_i2c\nvoid initScreen() {\n if (getWLCDI2C()->lcd != nullptr) {\n delete getWLCDI2C()->lcd;\n }\n\n getWLCDI2C()->lcd = new codal::I2C_LCD(getWLCDI2C()->i2c, 0x4E, 16, 2);\n getWLCDI2C()->lcd->init();\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * @brief Initialise the 16x2 screen with specific address\n *\n * @param address the hexadecimal address of the screen, eg: \"4E\"\n */\n//% blockId=\"I2C_LCD_INIT_ADDRESS\"\n//% block=\"init i2c LCD 0x%address\"\n//% weight=99\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid initScreenAddress(String address) {\n if (getWLCDI2C()->lcd != nullptr) {\n delete getWLCDI2C()->lcd;\n }\n\n getWLCDI2C()->lcd = new codal::I2C_LCD(getWLCDI2C()->i2c, strAddressToNumber(address), 16, 2);\n getWLCDI2C()->lcd->init();\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"I2C_LCD_SET_CURSOR\"\n//% block=\"set cursor position |at x %x|y %y\"\n//% weight=89\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid setCursor(uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n//% blockId=\"I2C_LCD_SHOW_NUMBER\"\n//% block=\"show number %n\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowNumber(int n) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n//% blockId=\"I2C_LCD_SHOW_STRING\"\n//% block=\"show string %s\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowString(String s) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(s->getUTF8Data());\n}\n\n/**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_VALUE\"\n//% block=\"show value %name = %value\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowValue(String name, int value) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(name->getUTF8Data());\n getWLCDI2C()->lcd->print(':');\n getWLCDI2C()->lcd->print(value);\n}\n\n/**\n * Clear all display content\n */\n//% blockId=\"I2C_LCD_CLEAR\"\n//% block=\"clear screen\"\n//% weight=85\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid clear() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->clear();\n}\n\n/**\n * Turn on lcd backlight\n */\n//% blockId=\"I2C_LCD_BACKLIGHT_ON\"\n//% block=\"turn on backlight\"\n//% group=\"Backlight\"\n//% weight=71\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid BacklightOn() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * Turn off lcd backlight\n */\n//% blockId=\"I2C_LCD_BACKLIGHT_OFF\"\n//% block=\"turn off backlight\"\n//% group=\"Backlight\"\n//% weight=70\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid BacklightOff() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->backlightOff();\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_NUMBER_AT_POS\"\n//% block=\"show number %n|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid ShowNumberAtPos(int n, uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n ShowNumber(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_STRING_AT_POS\"\n//% block=\"show string %s|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid ShowStringAtPos(String s, uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n ShowString(s);\n}\n} // namespace lcd_i2c", "ns.ts": "/**\n * Character lcd support\n */\n//% icon=\"\\uf0ae\" color=\"#219E42\" blockGap=8\n//% groups='[\"Display\", \"Configuration\"]'\n//% block=\"LCD I2C\"\nnamespace lcd_i2c {\n\n}", - "pxt.json": "{\n \"name\": \"lcd_i2c\",\n \"description\": \"Support for I2C Characeter LCD display (not grove one)\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd_i2c.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd_i2c.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"lcd_i2c\",\n \"description\": \"Support for I2C Characeter LCD display (not grove one)\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd_i2c.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd_i2c.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"lcd_i2c\": {\n \"simulationBehavior\": \"lcd_i2c\",\n \"visual\": {\n \"builtIn\": \"lcd_i2c\",\n \"width\": 322.7900085449219,\n \"height\": 147.52467,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 15,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 30,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 45,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 60,\n \"y\": 8.037069860858837\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n }\n ],\n \"assembly\": [\n { \"part\": true },\n { \"pinIndices\": [0] },\n { \"pinIndices\": [1] },\n { \"pinIndices\": [2, 3] }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace lcd_i2c {\n\n /**\n * @brief Initialise the 16x2 screen with address 0x4E\n */\n //% blockId=\"I2C_LCD_INIT\"\n //% block=\"init i2c LCD\"\n //% weight=100\n //% blockGap=8\n //% parts=lcd_i2c shim=lcd_i2c::initScreen\n function initScreen(): void;\n\n /**\n * @brief Initialise the 16x2 screen with specific address\n *\n * @param address the hexadecimal address of the screen, eg: \"4E\"\n */\n //% blockId=\"I2C_LCD_INIT_ADDRESS\"\n //% block=\"init i2c LCD 0x%address\"\n //% weight=99\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::initScreenAddress\n function initScreenAddress(address: string): void;\n\n /**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"I2C_LCD_SET_CURSOR\"\n //% block=\"set cursor position |at x %x|y %y\"\n //% weight=89\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::setCursor\n function setCursor(x: uint8, y: uint8): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n //% blockId=\"I2C_LCD_SHOW_NUMBER\"\n //% block=\"show number %n\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowNumber\n function ShowNumber(n: int32): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n //% blockId=\"I2C_LCD_SHOW_STRING\"\n //% block=\"show string %s\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowString\n function ShowString(s: string): void;\n\n /**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_VALUE\"\n //% block=\"show value %name = %value\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowValue\n function ShowValue(name: string, value: int32): void;\n\n /**\n * Clear all display content\n */\n //% blockId=\"I2C_LCD_CLEAR\"\n //% block=\"clear screen\"\n //% weight=85\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::clear\n function clear(): void;\n\n /**\n * Turn on lcd backlight\n */\n //% blockId=\"I2C_LCD_BACKLIGHT_ON\"\n //% block=\"turn on backlight\"\n //% group=\"Backlight\"\n //% weight=71\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::BacklightOn\n function BacklightOn(): void;\n\n /**\n * Turn off lcd backlight\n */\n //% blockId=\"I2C_LCD_BACKLIGHT_OFF\"\n //% block=\"turn off backlight\"\n //% group=\"Backlight\"\n //% weight=70\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::BacklightOff\n function BacklightOff(): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_NUMBER_AT_POS\"\n //% block=\"show number %n|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowNumberAtPos\n function ShowNumberAtPos(n: int32, x: uint8, y: uint8): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_STRING_AT_POS\"\n //% block=\"show string %s|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowStringAtPos\n function ShowStringAtPos(s: string, x: uint8, y: uint8): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_lcd_i2c.h": "#include \"pxt.h\"\n#include \"STM32I2C.h\"\n#include \"i2c_lcd.h\"\n\nnamespace pxt {\nclass WLCDI2C {\n public:\n codal::STM32I2C i2c;\n codal::I2C_LCD *lcd;\n WLCDI2C() : i2c(*LOOKUP_PIN(SDA), *LOOKUP_PIN(SCL)), lcd(nullptr) {}\n};\n} // namespace pxt" diff --git a/target.json b/target.json index dacb9f3..15cdd41 100644 --- a/target.json +++ b/target.json @@ -576,9 +576,10 @@ "ignoreDocsErrors": true, "uploadDocs": true, "versions": { - "branch": "main", - "commits": "https://github.com/letssteam/pxt-lets-steam/commits/f27999bbfa3f7b9efec725065f3f4048147033c9", - "target": "1.0.31", + "branch": "v1.0.32", + "tag": "v1.0.32", + "commits": "https://github.com/letssteam/pxt-lets-steam/commits/ca67d4a99b3f90769325fe37ffb2458c3b894b50", + "target": "1.0.32", "pxt": "7.4.12" }, "blocksprj": { @@ -651,7 +652,7 @@ "pxt-core.d.ts": "/// \n\ninterface Array {\n /**\n * Get or set the length of an array. This number is one more than the index of the last element the array.\n */\n //% shim=Array_::length weight=84\n //% blockId=\"lists_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"arrays\"\n length: number;\n\n /**\n * Append a new element to an array.\n * @param items New elements of the Array.\n */\n //% help=arrays/push\n //% shim=Array_::push weight=50\n //% blockId=\"array_push\" block=\"%list| add value %value| to end\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n push(item: T): void;\n\n /**\n * Concatenates the values with another array.\n * @param arr The other array that is being concatenated with\n */\n //% helper=arrayConcat weight=40\n concat(arr: T[]): T[];\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=45\n //% blockId=\"array_pop\" block=\"get and remove last value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n pop(): T;\n\n /**\n * Reverse the elements in an array. The first array element becomes the last, and the last array element becomes the first.\n */\n //% help=arrays/reverse\n //% helper=arrayReverse weight=10\n //% blockId=\"array_reverse\" block=\"reverse %list\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n reverse(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=30\n //% blockId=\"array_shift\" block=\"get and remove first value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n shift(): T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=25\n //% blockId=\"array_unshift\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n //unshift(...values:T[]): number; //rest is not supported in our compiler yet.\n unshift(value: T): number;\n\n /**\n * Return a section of an array.\n * @param start The beginning of the specified portion of the array. eg: 0\n * @param end The end of the specified portion of the array. eg: 0\n */\n //% help=arrays/slice\n //% helper=arraySlice weight=41 blockNamespace=\"arrays\"\n slice(start?: number, end?: number): T[];\n\n /**\n * Remove elements from an array.\n * @param start The zero-based location in the array from which to start removing elements. eg: 0\n * @param deleteCount The number of elements to remove. eg: 0\n */\n //% helper=arraySplice weight=40\n splice(start: number, deleteCount: number): void;\n\n /**\n * joins all elements of an array into a string and returns this string.\n * @param sep the string separator\n */\n //% helper=arrayJoin weight=40\n join(sep?: string): string;\n\n /**\n * Tests whether at least one element in the array passes the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arraySome weight=40\n some(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Tests whether all elements in the array pass the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayEvery weight=40\n every(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Sort the elements of an array in place and returns the array. The sort is not necessarily stable.\n * @param specifies a function that defines the sort order. If omitted, the array is sorted according to the prmitive type\n */\n //% helper=arraySort weight=40\n sort(callbackfn?: (value1: T, value2: T) => number): T[];\n\n /**\n * Call a defined callback function on each element of an array, and return an array containing the results.\n * @param callbackfn A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayMap weight=40\n map(callbackfn: (value: T, index: number) => U): U[];\n\n /**\n * Call a defined callback function on each element of an array.\n * @param callbackfn A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayForEach weight=40\n forEach(callbackfn: (value: T, index: number) => void): void;\n\n /**\n * Return the elements of an array that meet the condition specified in a callback function.\n * @param callbackfn A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayFilter weight=40\n filter(callbackfn: (value: T, index: number) => boolean): T[];\n\n /**\n * Fills all the elements of an array from a start index to an end index with a static value. The end index is not included.\n */\n //% helper=arrayFill weight=39\n fill(value: T, start?: number, end?: number): T[];\n\n /**\n * Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.\n * @param callbackfn\n */\n //% helper=arrayFind weight=40\n find(callbackfn: (value: T, index: number) => boolean): T;\n\n /**\n * Call the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n * @param callbackfn A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.\n * @param initialValue Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n */\n //% helper=arrayReduce weight=40\n reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;\n\n\n /** Remove the first occurence of an object. Returns true if removed. */\n //% shim=Array_::removeElement weight=48\n removeElement(element: T): boolean;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=47\n //% blockId=\"array_removeat\" block=\"%list| get and remove value at %index\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n removeAt(index: number): T;\n\n /**\n * Insert the value at a particular index, increases length by 1\n * @param index the zero-based position in the list to insert the value, eg: 0\n * @param the value to insert, eg: 0\n */\n //% help=arrays/insert-at\n //% shim=Array_::insertAt weight=20\n //% blockId=\"array_insertAt\" block=\"%list| insert at %index| value %value\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n insertAt(index: number, value: T): void;\n\n /**\n * Return the index of the first occurrence of a value in an array.\n * @param item The value to locate in the array.\n * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n */\n //% help=arrays/index-of\n //% shim=Array_::indexOf weight=40\n //% blockId=\"array_indexof\" block=\"%list| find index of %value\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n indexOf(item: T, fromIndex?: number): number;\n\n /**\n * Get the value at a particular index\n * @param index the zero-based position in the list of the item, eg: 0\n */\n //% help=arrays/get\n //% shim=Array_::getAt weight=85\n get(index: number): T;\n\n /**\n * Store a value at a particular index\n * @param index the zero-based position in the list to store the value, eg: 0\n * @param value the value to insert, eg: 0\n */\n //% help=arrays/set\n //% shim=Array_::setAt weight=84\n set(index: number, value: T): void;\n\n /**\n * Return a random value from the array\n */\n //% help=arrays/pick-random\n //% helper=arrayPickRandom weight=25\n //% blockId=\"array_pickRandom\" block=\"get random value from %list\"\n //% blockNamespace=\"arrays\"\n //% group=\"Read\"\n _pickRandom(): T;\n\n [n: number]: T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=24\n //% blockId=\"array_unshift_statement\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.unshift\"\n //% group=\"Modify\"\n _unshiftStatement(value: T): void;\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=44\n //% blockId=\"array_pop_statement\" block=\"remove last value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.pop\"\n //% group=\"Modify\"\n _popStatement(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=29\n //% blockId=\"array_shift_statement\" block=\"remove first value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.shift\"\n //% group=\"Modify\"\n _shiftStatement(): void;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=14\n //% blockId=\"array_removeat_statement\" block=\"%list| remove value at %index\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.removeAt\"\n //% group=\"Modify\"\n _removeAtStatement(index: number): void;\n}\n\ndeclare interface String {\n // This block is currently disabled in favor of the built-in Blockly \"Create text with\" block, which compiles to \"\" + \"\"\n // Add % sign back to the block annotation to re-enable\n /**\n * Returns a string that contains the concatenation of two or more strings.\n * @param other The string to append to the end of the string.\n */\n //% shim=String_::concat weight=49\n //% blockId=\"string_concat\" blockNamespace=\"text\"\n // block=\"join %list=text|%other\"\n concat(other: string): string;\n\n /**\n * Return the character at the specified index.\n * @param index The zero-based index of the desired character.\n */\n //% shim=String_::charAt weight=48\n //% help=text/char-at\n //% blockId=\"string_get\" block=\"char from %this=text|at %pos\" blockNamespace=\"text\"\n charAt(index: number): string;\n\n /** Returns the length of a String object. */\n //% property shim=String_::length weight=47\n //% blockId=\"text_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"text\"\n length: number;\n\n /**\n * Return the Unicode value of the character at the specified location.\n * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\n */\n //% shim=String_::charCodeAt\n charCodeAt(index: number): number;\n\n /**\n * See how the order of characters in two strings is different (in ASCII encoding).\n * @param that String to compare to target string\n */\n //% shim=String_::compare\n //% help=text/compare\n //% blockId=\"string_compare\" block=\"compare %this=text| to %that\" blockNamespace=\"text\"\n compare(that: string): number;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param length number of characters to extract, eg: 10\n */\n //% helper=stringSubstr\n //% help=text/substr\n //% blockId=\"string_substr\" block=\"substring of %this=text|from %start|of length %length\" blockNamespace=\"text\"\n substr(start: number, length?: number): string;\n\n /**\n * Return the current string with the first occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplace\n replace(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return the current string with each occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplaceAll\n replaceAll(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param end one-past-last character index\n */\n //% helper=stringSlice\n slice(start: number, end?: number): string;\n\n /** Returns a value indicating if the string is empty */\n //% helper=stringEmpty\n //% help=text/is-empty\n //% blockId=\"string_isempty\" blockNamespace=\"text\"\n //% block=\"%this=text| is empty\"\n isEmpty(): boolean;\n\n /**\n * Returns the position of the first occurrence of a specified value in a string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::indexOf\n //% help=text/index-of\n //% blockId=\"string_indexof\" blockNamespace=\"text\"\n //% block=\"%this=text|find index of %searchValue\"\n indexOf(searchValue: string, start?: number): number;\n\n /**\n * Determines whether a string contains the characters of a specified string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::includes\n //% help=text/includes\n //% blockId=\"string_includes\" blockNamespace=\"text\"\n //% block=\"%this=text|includes %searchValue\"\n includes(searchValue: string, start?: number): boolean;\n\n /**\n * Splits the string according to the separators\n * @param separator\n * @param limit\n */\n //% helper=stringSplit\n //% help=text/split\n //% blockId=\"string_split\" blockNamespace=\"text\"\n //% block=\"split %this=text|at %separator\"\n split(separator?: string, limit?: number): string[];\n\n /**\n * Return a substring of the current string with whitespace removed from both ends\n */\n //% helper=stringTrim\n trim(): string;\n\n /**\n * Converts the string to upper case characters.\n */\n //% helper=stringToUpperCase\n //% help=text/to-upper-case\n toUpperCase(): string;\n\n /**\n * Converts the string to lower case characters.\n */\n //% helper=stringToLowerCase\n //% help=text/to-lower-case\n toLowerCase(): string;\n\n [index: number]: string;\n}\n\n/**\n * Convert a string to a number.\n * @param s A string to convert into a number. eg: 123\n */\n//% shim=String_::toNumber\n//% help=text/parse-float\n//% blockId=\"string_parsefloat\" block=\"parse to number %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\ndeclare function parseFloat(text: string): number;\n\n/**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n//% blockId=\"device_random\" block=\"pick random %min|to %limit\"\n//% blockNamespace=\"Math\"\n//% help=math/randint\n//% shim=Math_::randomRange\ndeclare function randint(min: number, max: number): number;\n\ninterface Object { }\ninterface Function {\n __assignableToFunction: Function;\n}\ninterface IArguments {\n __assignableToIArguments: IArguments;\n}\ninterface RegExp {\n __assignableToRegExp: RegExp;\n}\ntype TemplateStringsArray = Array;\n\ntype uint8 = number;\ntype uint16 = number;\ntype uint32 = number;\ntype int8 = number;\ntype int16 = number;\ntype int32 = number;\n\n\ndeclare interface Boolean {\n /**\n * Returns a string representation of an object.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Combine, split, and search text strings.\n*/\n//% blockNamespace=\"text\"\ndeclare namespace String {\n\n /**\n * Make a string from the given ASCII character code.\n */\n //% help=math/from-char-code\n //% shim=String_::fromCharCode weight=1\n //% blockNamespace=\"text\" blockId=\"stringFromCharCode\" block=\"text from char code %code\"\n function fromCharCode(code: number): string;\n}\n\ndeclare interface Number {\n /**\n * Returns a string representation of a number.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Add, remove, and replace items in lists.\n*/\n//% blockNamespace=\"Arrays\"\ndeclare namespace Array {\n /**\n * Check if a given object is an array.\n */\n //% shim=Array_::isArray\n function isArray(obj: any): boolean;\n}\n\ndeclare namespace Object {\n /**\n * Return the field names in an object.\n */\n //% shim=pxtrt::keysOf\n function keys(obj: any): string[];\n}\n\n/**\n * More complex operations with numbers.\n*/\ndeclare namespace Math {\n /**\n * Returns the value of a base expression taken to a specified power.\n * @param x The base value of the expression.\n * @param y The exponent value of the expression.\n */\n //% shim=Math_::pow\n function pow(x: number, y: number): number;\n\n /**\n * Returns a pseudorandom number between 0 and 1.\n */\n //% shim=Math_::random\n //% help=math/random\n function random(): number;\n\n /**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n //% blockId=\"device_random_deprecated\" block=\"pick random %min|to %limit\"\n //% help=math/random-range deprecated\n //% shim=Math_::randomRange\n function randomRange(min: number, max: number): number;\n\n /**\n * Returns the natural logarithm (base e) of a number.\n * @param x A number\n */\n //% shim=Math_::log\n //% help=math\n function log(x: number): number;\n\n /**\n * Returns returns ``e^x``.\n * @param x A number\n */\n //% shim=Math_::exp\n //% help=math\n function exp(x: number): number;\n\n /**\n * Returns the sine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::sin\n //% help=math/trigonometry\n function sin(x: number): number;\n\n /**\n * Returns the cosine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::cos\n //% help=math/trigonometry\n function cos(x: number): number;\n\n /**\n * Returns the tangent of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::tan\n //% help=math/trigonometry\n function tan(x: number): number;\n\n /**\n * Returns the arcsine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::asin\n //% help=math/trigonometry\n function asin(x: number): number;\n\n /**\n * Returns the arccosine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::acos\n //% help=math/trigonometry\n function acos(x: number): number;\n\n /**\n * Returns the arctangent (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::atan\n //% help=math/trigonometry\n function atan(x: number): number;\n\n /**\n * Returns the arctangent of the quotient of its arguments.\n * @param y A number\n * @param x A number\n */\n //% shim=Math_::atan2\n //% help=math/trigonometry\n function atan2(y: number, x: number): number;\n\n /**\n * Returns the square root of a number.\n * @param x A numeric expression.\n */\n //% shim=Math_::sqrt\n //% help=math\n function sqrt(x: number): number;\n\n /**\n * Returns the smallest number greater than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::ceil\n //% help=math\n function ceil(x: number): number;\n\n /**\n * Returns the greatest number less than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::floor\n //% help=math\n function floor(x: number): number;\n\n /**\n * Returns the number with the decimal part truncated.\n * @param x A numeric expression.\n */\n //% shim=Math_::trunc\n //% help=math\n function trunc(x: number): number;\n\n /**\n * Returns a supplied numeric expression rounded to the nearest number.\n * @param x The value to be rounded to the nearest number.\n */\n //% shim=Math_::round\n //% help=math\n function round(x: number): number;\n\n /**\n * Returns the value of integer signed 32 bit multiplication of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::imul\n //% help=math\n function imul(x: number, y: number): number;\n\n /**\n * Returns the value of integer signed 32 bit division of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::idiv\n //% help=math\n function idiv(x: number, y: number): number;\n}\n\ndeclare namespace control {\n //% shim=_control::_onCodeStart\n export function _onCodeStart(arg: any): void;\n\n //% shim=_control::_onCodeStop\n export function _onCodeStop(arg: any): void;\n}", "pxt-helpers.ts": "type Action = () => void;\n\n/**\n * Constant representing Not-A-Number.\n */\nconst NaN = 0 / 0\n\n/**\n * Constant representing positive infinity.\n */\nconst Infinity = 1 / 0\n\nfunction isNaN(x: number) {\n x = +x // convert to number\n return x !== x\n}\n\nnamespace Number {\n /**\n * Check if a given value is of type Number and it is a NaN.\n */\n export function isNaN(x: any): boolean {\n return typeof x == \"number\" && x !== x\n }\n}\n\n/**\n * A dictionary from string key to string values\n */\ninterface StringMap {\n [index: string]: string;\n}\n\n/**\n * Convert a string to an integer.\n * @param text A string to convert into an integral number. eg: \"123\"\n * @param radix optional A value between 2 and 36 that specifies the base of the number in text.\n * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n * All other strings are considered decimal.\n */\n//% help=text/parse-int\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\n//% blockHidden=1\nfunction parseInt(text: string, radix?: number): number {\n // roughly based on https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2\n // with some consideration for avoiding unnecessary slices where easy\n if (!text || (radix != null && (radix < 2 || radix > 36)))\n return NaN;\n\n let start = 0;\n while (start < text.length && helpers.isWhitespace(text.charCodeAt(start)))\n ++start;\n\n if (start === text.length)\n return NaN;\n\n const numberOffset = 48; // 0\n const numCount = 10;\n const letterOffset = 97; // a\n const letterCount = 26;\n const lowerCaseMask = 0x20;\n\n let sign = 1;\n switch (text.charAt(start)) {\n case \"-\":\n sign = -1;\n // fallthrough\n case \"+\":\n ++start;\n }\n\n if ((!radix || radix == 16)\n && \"0\" === text[start]\n && (\"x\" === text[start + 1] || \"X\" === text[start + 1])) {\n radix = 16;\n start += 2;\n } else if (!radix) {\n radix = 10;\n }\n\n let output = 0;\n let hasDigit = false;\n for (let i = start; i < text.length; ++i) {\n const code = text.charCodeAt(i) | lowerCaseMask;\n let val: number = undefined;\n\n if (code >= numberOffset && code < numberOffset + numCount)\n val = code - numberOffset;\n else if (code >= letterOffset && code < letterOffset + letterCount)\n val = numCount + code - letterOffset;\n\n if (val == undefined || val >= radix) {\n if (!hasDigit) {\n return NaN;\n }\n break;\n }\n hasDigit = true;\n output = output * radix + val;\n }\n\n return sign * output;\n}\n\nnamespace helpers {\n export function arrayFill(O: T[], value: T, start?: number, end?: number) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n // Steps 3-5.\n const len = O.length >>> 0;\n\n // Steps 6-7.\n const relativeStart = start === undefined ? 0 : start >> 0;\n\n // Step 8.\n let k = relativeStart < 0 ?\n Math.max(len + relativeStart, 0) :\n Math.min(relativeStart, len);\n\n // Steps 9-10.\n const relativeEnd = end === undefined ? len : end >> 0;\n\n // Step 11.\n const final = relativeEnd < 0 ?\n Math.max(len + relativeEnd, 0) :\n Math.min(relativeEnd, len);\n\n // Step 12.\n while (k < final) {\n O[k] = value;\n k++;\n }\n\n // Step 13.\n return O;\n }\n\n export function arraySplice(arr: T[], start: number, len: number) {\n if (start < 0) {\n return;\n }\n for (let i = 0; i < len; ++i) {\n arr.removeAt(start)\n }\n }\n\n export function arrayReverse(arr: T[]): void {\n let len = arr.length;\n for (let i = 0; i < len / 2; i++) {\n swap(arr, i, len - i - 1);\n }\n }\n\n export function arrayShift(arr: T[]): T {\n return arr.removeAt(0);\n }\n\n export function arrayJoin(arr: T[], sep?: string): string {\n if (sep === undefined || sep === null) {\n sep = \",\";\n }\n\n let r = \"\";\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n if (i > 0 && sep)\n r += sep;\n r += (arr[i] === undefined || arr[i] === null) ? \"\" : arr[i];\n }\n return r;\n }\n\n /*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n export function arrayUnshift(arr: T[], ...values: T[]) : number {\n for(let i = values.length; i > 0; --i) {\n arr.insertAt(0, values[i - 1]);\n }\n return arr.length;\n }\n */\n export function arrayUnshift(arr: T[], value: T): number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap(arr: T[], i: number, j: number): void {\n let temp: T = arr[i];\n arr[i] = arr[j];\n arr[j] = temp;\n }\n\n function sortHelper(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (arr.length <= 0 || !callbackfn) {\n return arr;\n }\n let len = arr.length;\n // simple selection sort.\n for (let i = 0; i < len - 1; ++i) {\n for (let j = i + 1; j < len; ++j) {\n if (callbackfn(arr[i], arr[j]) > 0) {\n swap(arr, i, j);\n }\n }\n }\n return arr;\n }\n\n export function arraySort(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (!callbackfn && arr.length > 1) {\n callbackfn = (a, b) => {\n // default is sort as if the element were a string, with null < undefined\n const aIsUndef = a === undefined;\n const bIsUndef = b === undefined;\n if (aIsUndef && bIsUndef) return 0;\n else if (aIsUndef) return 1;\n else if (bIsUndef) return -1;\n\n const aIsNull = a === null;\n const bIsNull = b === null;\n if (aIsNull && bIsNull) return 0;\n else if (aIsNull) return 1;\n else if (bIsNull) return -1;\n\n return (a + \"\").compare(b + \"\");\n }\n }\n return sortHelper(arr, callbackfn);\n }\n\n export function arrayMap(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n let res: U[] = []\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n res.push(callbackfn(arr[i], i))\n }\n return res\n }\n\n export function arraySome(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (callbackfn(arr[i], i))\n return true;\n return false;\n }\n\n export function arrayEvery(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (!callbackfn(arr[i], i))\n return false;\n return true;\n }\n\n export function arrayForEach(arr: T[], callbackfn: (value: T, index: number) => void): void {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n callbackfn(arr[i], i);\n }\n }\n\n export function arrayFilter(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n let res: T[] = []\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) res.push(v)\n }\n return res\n }\n\n export function arrayFind(arr: T[], callbackfn: (value: T, index: number) => boolean): T {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) return v;\n }\n return undefined;\n }\n\n export function arrayReduce(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n initialValue = callbackfn(initialValue, arr[i], i)\n }\n return initialValue\n }\n\n export function arrayConcat(arr: T[], otherArr: T[]): T[] {\n let out: T[] = [];\n for (let value of arr) {\n out.push(value);\n }\n for (let value of otherArr) {\n out.push(value);\n }\n return out;\n }\n\n export function arrayPickRandom(arr: T[]): T {\n return arr[Math.randomRange(0, arr.length - 1)];\n }\n\n export function arraySlice(arr: T[], start?: number, end?: number): T[] {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\n const res: T[] = [];\n const len = arr.length;\n\n if (start === undefined)\n start = 0;\n else if (start < 0)\n start = Math.max(len + start, 0);\n\n if (start > len)\n return res;\n\n if (end === undefined)\n end = len;\n else if (end < 0)\n end = len + end;\n\n if (end > len)\n end = len;\n\n for (let i = start; i < end; ++i) {\n res.push(arr[i]);\n }\n return res;\n }\n\n export function stringReplace(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const ind = s.indexOf(toReplace);\n if (ind == -1)\n return s;\n\n const begin = s.slice(0, ind);\n const end = s.slice(ind + toReplace.length);\n\n if (typeof replacer == \"string\" || !replacer) {\n return begin + replacer + end;\n } else {\n return begin + replacer(toReplace) + end;\n }\n }\n\n export function stringReplaceAll(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const split = s.split(toReplace);\n const empty = toReplace.isEmpty();\n\n let output = (empty ? applyReplace(toReplace, replacer) : \"\");\n\n if (split.length) {\n output += split[0];\n }\n\n for (let i = 1; i < split.length; ++i) {\n output += applyReplace(toReplace, replacer) + split[i];\n }\n\n if (!s.isEmpty() && empty) {\n output += applyReplace(toReplace, replacer);\n }\n\n return output;\n\n function applyReplace(r: string, replacer: string | ((sub: string) => string)): string {\n if (typeof replacer == \"string\" || !replacer) {\n return replacer as string;\n } else {\n return replacer(r);\n }\n }\n }\n\n //% shim=String_::substr\n declare function stringSubstrHelper(s: string, start: number, length?: number): string;\n\n export function stringSubstr(s: string, start: number, length?: number): string {\n length = length === undefined ? s.length : length || 0;\n return stringSubstrHelper(s, start, length);\n }\n\n export function stringSlice(s: string, start: number, end?: number): string {\n const len = s.length;\n\n if (start < 0) {\n start = Math.max(len + start, 0);\n }\n\n if (end === undefined) {\n end = len;\n } else if (end === null) {\n end = 0;\n }\n\n if (end < 0) {\n end = len + end;\n }\n\n return stringSubstrHelper(s, start, end - start);\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleUpperCase())\n export function stringToUpperCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (97 <= c && c <= 122) {\n r += s.slice(prev, i) + String.fromCharCode(c - 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleLowerCase())\n export function stringToLowerCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (65 <= c && c <= 90) {\n r += s.slice(prev, i) + String.fromCharCode(c + 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n export function stringSplit(S: string, separator?: string, limit?: number): string[] {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.split\n const A: string[] = [];\n let lim = 0;\n if (limit === undefined)\n lim = (1 << 29) - 1; // spec says 1 << 53, leaving it at 29 for constant folding\n else if (limit < 0)\n lim = 0;\n else\n lim = limit | 0;\n const s = S.length;\n let p = 0;\n const R = separator;\n if (lim == 0)\n return A;\n if (separator === undefined) {\n A[0] = S;\n return A;\n }\n if (s == 0) {\n let z = splitMatch(S, 0, R);\n if (z > -1) return A;\n A[0] = S;\n return A;\n }\n let T: string;\n let q = p;\n while (q != s) {\n let e = splitMatch(S, q, R);\n if (e < 0) q++;\n else {\n if (e == p) q++;\n else {\n T = stringSlice(S, p, q);\n A.push(T);\n if (A.length == lim) return A;\n p = e;\n q = p;\n }\n }\n }\n T = stringSlice(S, p, q);\n A.push(T);\n return A;\n }\n\n function splitMatch(S: string, q: number, R: string): number {\n const r = R.length;\n const s = S.length;\n if (q + r > s) return -1;\n for (let i = 0; i < r; ++i) {\n if (S[q + i] != R[i])\n return -1;\n }\n return q + r;\n }\n\n export function stringTrim(s: string): string {\n let start = 0;\n let end = s.length - 1;\n\n while (start <= end && isWhitespace(s.charCodeAt(start)))\n ++start;\n\n while (end > start && isWhitespace(s.charCodeAt(end)))\n --end;\n return s.slice(start, end + 1);\n }\n\n export function isWhitespace(c: number): boolean {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-white-space\n switch (c) {\n case 0x0009: // character tab\n case 0x000B: // line tab\n case 0x000C: // form feed\n case 0x0020: // space\n case 0x00A0: // no-break space\n case 0xFEFF: // zero width no break space\n case 0x000A: // line feed\n case 0x000D: // carriage return\n case 0x2028: // line separator\n case 0x2029: // paragraph separator\n return true;\n default:\n return false;\n }\n }\n\n export function stringEmpty(S: string): boolean {\n return !S;\n }\n}\n\nnamespace Math {\n export function clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n }\n\n /**\n * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\n * For example, the absolute value of -5 is the same as the absolute value of 5.\n * @param x A numeric expression for which the absolute value is needed.\n */\n //% help=math/abs\n export function abs(x: number): number {\n return x < 0 ? -x : x;\n }\n\n /**\n * Returns the sign of the x, indicating whether x is positive, negative or zero.\n * @param x The numeric expression to test\n */\n export function sign(x: number): number {\n if (x == 0) return 0;\n if (x > 0) return 1;\n return -1;\n }\n\n /**\n * Returns the larger of two supplied numeric expressions.\n */\n //% help=math/max\n export function max(a: number, b: number): number {\n if (a >= b) return a;\n return b;\n }\n\n /**\n * Returns the smaller of two supplied numeric expressions.\n */\n //% help=math/min\n export function min(a: number, b: number): number {\n if (a <= b) return a;\n return b;\n }\n\n /**\n * Rounds ``x`` to a number with the given number of ``digits``\n * @param x the number to round\n * @param digits the number of resulting digits\n */\n //%\n export function roundWithPrecision(x: number, digits: number): number {\n digits = digits | 0;\n // invalid digits input\n if (digits <= 0) return Math.round(x);\n if (x == 0) return 0;\n let r = 0;\n do {\n const d = Math.pow(10, digits);\n r = Math.round(x * d) / d;\n digits++;\n } while (r == 0 && digits < 21);\n return r;\n }\n}\n\n\n//% blockHidden=1\nnamespace __internal {\n /**\n * A shim to render a boolean as a down/up toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleDownUp block=\"%down\"\n //% down.fieldEditor=toggledownup\n //% down.fieldOptions.decompileLiterals=true\n export function __downUp(down: boolean): boolean {\n return down;\n }\n\n /**\n * A shim to render a boolean as a up/down toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleUpDown block=\"%up\"\n //% up.fieldEditor=toggleupdown\n //% up.fieldOptions.decompileLiterals=true\n export function __upDown(up: boolean): boolean {\n return up;\n }\n\n /**\n * A shim to render a boolean as a high/low toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleHighLow block=\"%high\"\n //% high.fieldEditor=togglehighlow\n //% high.fieldOptions.decompileLiterals=true\n export function __highLow(high: boolean): boolean {\n return high;\n }\n\n /**\n * A shim to render a boolean as a on/off toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleOnOff block=\"%on\"\n //% on.fieldEditor=toggleonoff\n //% on.fieldOptions.decompileLiterals=true\n export function __onOff(on: boolean): boolean {\n return on;\n }\n\n /**\n * A shim to render a boolean as a yes/no toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleYesNo block=\"%yes\"\n //% yes.fieldEditor=toggleyesno\n //% yes.fieldOptions.decompileLiterals=true\n export function __yesNo(yes: boolean): boolean {\n return yes;\n }\n\n /**\n * A shim to render a boolean as a win/lose toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleWinLose block=\"%win\"\n //% win.fieldEditor=togglewinlose\n //% win.fieldOptions.decompileLiterals=true\n export function __winLose(win: boolean): boolean {\n return win;\n }\n\n /**\n * Get the color wheel field editor\n * @param color color, eg: #ff0000\n */\n //% blockId=colorNumberPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colornumber\" value.fieldOptions.decompileLiterals=true\n //% value.defl='#ff0000'\n //% value.fieldOptions.colours='[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]'\n //% value.fieldOptions.columns=4 value.fieldOptions.className='rgbColorPicker'\n export function __colorNumberPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n export function __colorWheelPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor using HSV values\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelHsvPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n //% value.fieldOptions.channel=hsvfast\n export function __colorWheelHsvPicker(value: number) {\n return value;\n }\n\n /**\n * A speed picker\n * @param speed the speed, eg: 50\n */\n //% blockId=speedPicker block=\"%speed\" shim=TD_ID\n //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1\n export function __speedPicker(speed: number): number {\n return speed;\n }\n\n /**\n * A turn ratio picker\n * @param turnratio the turn ratio, eg: 0\n */\n //% blockId=turnRatioPicker block=\"%turnratio\" shim=TD_ID\n //% turnratio.fieldEditor=\"turnratio\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1\n export function __turnRatioPicker(turnratio: number): number {\n return turnratio;\n }\n\n /**\n * A field editor that displays a protractor\n */\n //% blockId=protractorPicker block=\"%angle\"\n //% shim=TD_ID\n //% angle.fieldEditor=protractor\n //% angle.fieldOptions.decompileLiterals=1\n //% colorSecondary=\"#FFFFFF\"\n //% blockHidden=1\n export function __protractor(angle: number) {\n return angle;\n }\n\n /**\n * Get the time field editor\n * @param ms time duration in milliseconds, eg: 500, 1000\n */\n //% blockId=timePicker block=\"%ms\"\n //% blockHidden=true shim=TD_ID\n //% colorSecondary=\"#FFFFFF\"\n //% ms.fieldEditor=\"numberdropdown\" ms.fieldOptions.decompileLiterals=true\n //% ms.fieldOptions.data='[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]'\n export function __timePicker(ms: number): number {\n return ms;\n }\n}\n", "pxt.cpp": "#include \"pxtbase.h\"\n\nusing namespace std;\n\nnamespace pxt {\n\nAction mkAction(int totallen, RefAction *act) {\n check(getVTable(act)->classNo == BuiltInType::RefAction, PANIC_INVALID_BINARY_HEADER, 1);\n#ifdef PXT_VM\n check(act->initialLen <= totallen, PANIC_INVALID_BINARY_HEADER, 13);\n#endif\n\n if (totallen == 0) {\n return (TValue)act; // no closure needed\n }\n\n void *ptr = gcAllocate(sizeof(RefAction) + totallen * sizeof(void *));\n RefAction *r = new (ptr) RefAction();\n r->len = totallen;\n#ifdef PXT_VM\n r->numArgs = act->numArgs;\n r->initialLen = act->initialLen;\n r->flags = 0;\n#endif\n r->func = act->func;\n memset(r->fields, 0, r->len * sizeof(void *));\n\n MEMDBG(\"mkAction: start=%p => %p\", act, r);\n\n return (Action)r;\n}\n\nRefRecord *mkClassInstance(VTable *vtable) {\n intcheck(vtable->methods[0] == &RefRecord_destroy, PANIC_SIZE, 3);\n // intcheck(vtable->methods[1] == &RefRecord_print, PANIC_SIZE, 4);\n\n void *ptr = gcAllocate(vtable->numbytes);\n RefRecord *r = new (ptr) RefRecord(vtable);\n memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));\n MEMDBG(\"mkClass: vt=%p => %p\", vtable, r);\n return r;\n}\n\nTValue RefRecord::ld(int idx) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 1);\n return fields[idx];\n}\n\nTValue RefRecord::ldref(int idx) {\n // DMESG(\"LD %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 2);\n return fields[idx];\n}\n\nvoid RefRecord::st(int idx, TValue v) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 3);\n fields[idx] = v;\n}\n\nvoid RefRecord::stref(int idx, TValue v) {\n // DMESG(\"ST %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 4);\n fields[idx] = v;\n}\n\nvoid RefObject::destroyVT() {\n ((RefObjectMethod)getVTable(this)->methods[0])(this);\n}\n\n//%\nvoid deleteRefObject(RefObject *obj) {\n obj->destroyVT();\n}\n\nvoid RefObject::printVT() {\n ((RefObjectMethod)getVTable(this)->methods[1])(this);\n}\n\nvoid RefRecord_destroy(RefRecord *) {}\n\nvoid RefRecord_print(RefRecord *r) {\n DMESG(\"RefRecord %p size=%d bytes\", r, getVTable(r)->numbytes);\n}\n\nvoid Segment::set(unsigned i, TValue value) {\n if (i < size) {\n data[i] = value;\n } else if (i < Segment::MaxSize) {\n growByMin(i + 1);\n data[i] = value;\n } else {\n return;\n }\n if (length <= i) {\n length = i + 1;\n }\n\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::set\");\n this->print();\n#endif\n\n return;\n}\n\nstatic inline int growthFactor(int size) {\n if (size == 0) {\n return 4;\n }\n if (size < 64) {\n return size * 2; // Double\n }\n if (size < 512) {\n return size * 5 / 3; // Grow by 1.66 rate\n }\n // Grow by constant rate\n if ((unsigned)size + 256 < Segment::MaxSize)\n return size + 256;\n else\n return Segment::MaxSize;\n}\n\nvoid LLSegment::setLength(unsigned newLen) {\n if (newLen > Segment::MaxSize)\n return;\n\n if (newLen > size) {\n int newSize = growthFactor(size);\n if (newSize < (int)newLen)\n newSize = newLen;\n\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(xmalloc(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size) {\n memcpy(tmp, data, size * sizeof(TValue));\n }\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n // free older segment;\n xfree(data);\n\n data = tmp;\n size = newSize;\n } else if (newLen < length) {\n memset(data + newLen, 0, (length - newLen) * sizeof(TValue));\n }\n\n length = newLen;\n}\n\nvoid LLSegment::set(unsigned idx, TValue v) {\n if (idx >= Segment::MaxSize)\n return;\n if (idx >= length)\n setLength(idx + 1);\n data[idx] = v;\n}\n\nTValue LLSegment::pop() {\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = 0;\n return value;\n }\n return 0;\n}\n\nvoid LLSegment::destroy() {\n length = size = 0;\n xfree(data);\n data = nullptr;\n}\n\nvoid Segment::growByMin(ramint_t minSize) {\n ramint_t newSize = max(minSize, (ramint_t)growthFactor(size));\n\n if (size < newSize) {\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(gcAllocateArray(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size)\n memcpy(tmp, data, size * sizeof(TValue));\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n data = tmp;\n size = newSize;\n\n#ifdef DEBUG_BUILD\n DMESG(\"growBy - after reallocation\");\n this->print();\n#endif\n }\n // else { no shrinking yet; }\n return;\n}\n\nvoid Segment::ensure(ramint_t newSize) {\n if (newSize < size) {\n return;\n }\n growByMin(newSize);\n}\n\nvoid Segment::setLength(unsigned newLength) {\n if (newLength > size) {\n ensure(newLength);\n }\n length = newLength;\n return;\n}\n\nTValue Segment::pop() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::pop\");\n this->print();\n#endif\n\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = Segment::DefaultValue;\n return value;\n }\n return Segment::DefaultValue;\n}\n\n// this function removes an element at index i and shifts the rest of the elements to\n// left to fill the gap\nTValue Segment::remove(unsigned i) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::remove index:%d\", i);\n this->print();\n#endif\n if (i < length) {\n // value to return\n TValue ret = data[i];\n if (i + 1 < length) {\n // Move the rest of the elements to fill in the gap.\n memmove(data + i, data + i + 1, (length - i - 1) * sizeof(void *));\n }\n length--;\n data[length] = Segment::DefaultValue;\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::remove index:%d\", i);\n this->print();\n#endif\n return ret;\n }\n return Segment::DefaultValue;\n}\n\n// this function inserts element value at index i by shifting the rest of the elements right.\nvoid Segment::insert(unsigned i, TValue value) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::insert index:%d value:%d\", i, value);\n this->print();\n#endif\n\n if (i < length) {\n ensure(length + 1);\n\n // Move the rest of the elements to fill in the gap.\n memmove(data + i + 1, data + i, (length - i) * sizeof(void *));\n\n data[i] = value;\n length++;\n } else {\n // This is insert beyond the length, just call set which will adjust the length\n set(i, value);\n }\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::insert index:%d\", i);\n this->print();\n#endif\n}\n\nvoid Segment::print() {\n DMESG(\"Segment: %p, length: %d, size: %d\", data, (unsigned)length, (unsigned)size);\n for (unsigned i = 0; i < size; i++) {\n DMESG(\"-> %d\", (unsigned)(uintptr_t)data[i]);\n }\n}\n\nvoid Segment::destroy() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::destroy\");\n this->print();\n#endif\n length = size = 0;\n data = nullptr;\n}\n\nPXT_VTABLE_CTOR(RefCollection) {}\n\nvoid RefCollection::destroy(RefCollection *t) {\n t->head.destroy();\n}\n\nvoid RefCollection::print(RefCollection *t) {\n DMESG(\"RefCollection %p size=%d\", t, t->head.getLength());\n t->head.print();\n}\n\nPXT_VTABLE(RefAction, ValType::Function)\nRefAction::RefAction() : PXT_VTABLE_INIT(RefAction) {}\n\n// fields[] contain captured locals\nvoid RefAction::destroy(RefAction *t) {}\n\nvoid RefAction::print(RefAction *t) {\n#ifdef PXT_VM\n DMESG(\"RefAction %p pc=%X size=%d\", t, (uint32_t)t->func, t->len);\n#else\n DMESG(\"RefAction %p pc=%X size=%d\", t, (const uint8_t *)t->func - (const uint8_t *)bytecode,\n t->len);\n#endif\n}\n\nPXT_VTABLE_CTOR(RefRefLocal) {\n v = 0;\n}\n\nvoid RefRefLocal::print(RefRefLocal *t) {\n DMESG(\"RefRefLocal %p v=%p\", t, (void *)t->v);\n}\n\nvoid RefRefLocal::destroy(RefRefLocal *t) {\n decr(t->v);\n}\n\nPXT_VTABLE_CTOR(RefMap) {}\n\nvoid RefMap::destroy(RefMap *t) {\n t->keys.destroy();\n t->values.destroy();\n}\n\nint RefMap::findIdx(String key) {\n auto len = keys.getLength();\n auto data = (String *)keys.getData();\n\n // fast path\n for (unsigned i = 0; i < len; ++i) {\n if (data[i] == key)\n return i;\n }\n\n // slow path\n auto keylen = key->getUTF8Size();\n auto keydata = key->getUTF8Data();\n for (unsigned i = 0; i < len; ++i) {\n auto s = data[i];\n if (s->getUTF8Size() == keylen && memcmp(keydata, s->getUTF8Data(), keylen) == 0)\n return i;\n }\n\n return -1;\n}\n\nvoid RefMap::print(RefMap *t) {\n DMESG(\"RefMap %p size=%d\", t, t->keys.getLength());\n}\n\nvoid debugMemLeaks() {}\n\nvoid error(PXT_PANIC code, int subcode) {\n DMESG(\"Error: %d [%d]\", code, subcode);\n target_panic(code);\n}\n\n#ifndef PXT_VM\nuint16_t *bytecode;\n#endif\nTValue *globals;\n\nvoid checkStr(bool cond, const char *msg) {\n if (!cond) {\n while (true) {\n // uBit.display.scroll(msg, 100);\n // uBit.sleep(100);\n }\n }\n}\n\n#ifdef PXT_VM\nint templateHash() {\n return *(int*)&vmImg->infoHeader->hexHash;\n}\n\nint programHash() {\n return *(int*)&vmImg->infoHeader->programHash;\n}\n\nint getNumGlobals() {\n return (int)vmImg->infoHeader->allocGlobals;\n}\n\nString programName() {\n return mkString((char *)vmImg->infoHeader->name);\n}\n#else\nint templateHash() {\n return ((int *)bytecode)[4];\n}\n\nint programHash() {\n return ((int *)bytecode)[6];\n}\n\nint getNumGlobals() {\n return bytecode[16];\n}\n\nString programName() {\n return ((String *)bytecode)[15];\n}\n#endif\n\n#ifndef PXT_VM\nvoid variantNotSupported(const char *v) {\n DMESG(\"variant not supported: %s\", v);\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n}\n\nvoid exec_binary(unsigned *pc) {\n // XXX re-enable once the calibration code is fixed and [editor/embedded.ts]\n // properly prepends a call to [internal_main].\n // ::touch_develop::internal_main();\n\n // unique group for radio based on source hash\n // ::touch_develop::micro_bit::radioDefaultGroup = programHash();\n\n unsigned ver = *pc++;\n checkStr(ver == 0x4210, \":( Bad runtime version\");\n\n bytecode = *((uint16_t **)pc++); // the actual bytecode is here\n\n if (((uint32_t *)bytecode)[0] == 0x923B8E71) {\n variantNotSupported((const char *)bytecode + 16);\n return;\n }\n\n globals = (TValue *)app_alloc(sizeof(TValue) * getNumGlobals());\n memset(globals, 0, sizeof(TValue) * getNumGlobals());\n\n // can be any valid address, best in RAM for speed\n globals[0] = (TValue)&globals;\n\n // just compare the first word\n // TODO\n checkStr(((uint32_t *)bytecode)[0] == 0x923B8E70 && (unsigned)templateHash() == *pc,\n \":( Failed partial flash\");\n\n uintptr_t startptr = (uintptr_t)bytecode;\n\n startptr += 64; // header\n\n initPerfCounters();\n\n initRuntime();\n\n runAction0((Action)startptr);\n\n pxt::releaseFiber();\n}\n\nvoid start() {\n exec_binary((unsigned *)functionsAndBytecode);\n}\n#endif\n\n} // namespace pxt\n\nnamespace Array_ {\n//%\nbool isArray(TValue arr) {\n auto vt = getAnyVTable(arr);\n return vt && vt->classNo == BuiltInType::RefCollection;\n}\n} // namespace Array_\n\nnamespace pxtrt {\n//% expose\nRefCollection *keysOf(TValue v) {\n auto r = NEW_GC(RefCollection);\n MEMDBG(\"mkColl[keys]: => %p\", r);\n if (getAnyVTable(v) != &RefMap_vtable)\n return r;\n auto rm = (RefMap *)v;\n auto len = rm->keys.getLength();\n if (!len)\n return r;\n registerGCObj(r);\n r->setLength(len);\n auto dst = r->getData();\n memcpy(dst, rm->keys.getData(), len * sizeof(TValue));\n unregisterGCObj(r);\n return r;\n}\n//% expose\nTValue mapDeleteByString(RefMap *map, String key) {\n if (getAnyVTable((TValue)map) != &RefMap_vtable)\n soft_panic(PANIC_DELETE_ON_CLASS);\n int i = map->findIdx(key);\n if (i >= 0) {\n map->keys.remove(i);\n map->values.remove(i);\n }\n return TAG_TRUE;\n}\n\n} // namespace pxtrt\n", - "pxt.json": "{\n \"name\": \"base\",\n \"description\": \"The base library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"pxt-core.d.ts\",\n \"pxt.cpp\",\n \"gc.cpp\",\n \"configkeys.h\",\n \"pxtbase.h\",\n \"core.cpp\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"pxt-helpers.ts\",\n \"fixed.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"loops.cpp\",\n \"math.ts\",\n \"ns.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"control.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"poll.ts\",\n \"console.ts\",\n \"json.ts\",\n \"templates.ts\",\n \"eventcontext.ts\",\n \"pause.ts\",\n \"forever.ts\",\n \"utfdecoder.ts\",\n \"scheduling.ts\",\n \"controlmessage.ts\",\n \"perfcounters.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"partial\": true,\n \"yotta\": {\n \"optionalConfig\": {\n \"PXT_GC_CHECKS\": 0\n },\n \"userConfigs\": [\n {\n \"description\": \"(Diagnostics) Garbage Collection checks.\",\n \"config\": {\n \"PXT_GC_CHECKS\": 1\n }\n }\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"base\",\n \"description\": \"The base library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"pxt-core.d.ts\",\n \"pxt.cpp\",\n \"gc.cpp\",\n \"configkeys.h\",\n \"pxtbase.h\",\n \"core.cpp\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"pxt-helpers.ts\",\n \"fixed.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"loops.cpp\",\n \"math.ts\",\n \"ns.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"control.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"poll.ts\",\n \"console.ts\",\n \"json.ts\",\n \"templates.ts\",\n \"eventcontext.ts\",\n \"pause.ts\",\n \"forever.ts\",\n \"utfdecoder.ts\",\n \"scheduling.ts\",\n \"controlmessage.ts\",\n \"perfcounters.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"partial\": true,\n \"yotta\": {\n \"optionalConfig\": {\n \"PXT_GC_CHECKS\": 0\n },\n \"userConfigs\": [\n {\n \"description\": \"(Diagnostics) Garbage Collection checks.\",\n \"config\": {\n \"PXT_GC_CHECKS\": 1\n }\n }\n ]\n }\n}\n", "pxtbase.h": "#ifndef __PXTBASE_H\n#define __PXTBASE_H\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#pragma GCC diagnostic ignored \"-Wformat\"\n#pragma GCC diagnostic ignored \"-Warray-bounds\"\n\n// needed for gcc6; not sure why\n#undef min\n#undef max\n\n#define NOLOG(...) \\\n do { \\\n } while (0)\n\n#define MEMDBG NOLOG\n//#define MEMDBG DMESG\n#define MEMDBG2 NOLOG\n\n#include \"pxtconfig.h\"\n#include \"configkeys.h\"\n\n#ifndef PXT_UTF8\n#define PXT_UTF8 0\n#endif\n\n#if defined(PXT_VM)\n#include \n#if UINTPTR_MAX == 0xffffffff\n#define PXT32 1\n#elif UINTPTR_MAX == 0xffffffffffffffff\n#define PXT64 1\n#else\n#error \"UINTPTR_MAX has invalid value\"\n#endif\n#endif\n\n#define intcheck(...) check(__VA_ARGS__)\n//#define intcheck(...) do {} while (0)\n\n#ifdef PXT_USE_FLOAT\n#define NUMBER float\n#else\n#define NUMBER double\n#endif\n\n#include \n#include \n#include \n\n#ifdef POKY\nvoid *operator new(size_t size, void *ptr);\nvoid *operator new(size_t size);\n#else\n#include \n#endif\n\n#include \"platform.h\"\n#include \"pxtcore.h\"\n\n#ifndef PXT_REGISTER_RESET\n#define PXT_REGISTER_RESET(fn) ((void)0)\n#endif\n\n#define PXT_REFCNT_FLASH 0xfffe\n\n#define CONCAT_1(a, b) a##b\n#define CONCAT_0(a, b) CONCAT_1(a, b)\n// already provided in some platforms, like mbedos\n#ifndef STATIC_ASSERT\n#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) };\n#endif\n\n#ifndef ramint_t\n// this type limits size of arrays\n#if defined(__linux__) || defined(PXT_VM)\n// TODO fix the inline array accesses to take note of this!\n#define ramint_t uint32_t\n#else\n#define ramint_t uint16_t\n#endif\n#endif\n\n#ifndef PXT_IN_ISR\n#define PXT_IN_ISR() (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)\n#endif\n\n#ifdef POKY\ninline void *operator new(size_t, void *p) {\n return p;\n}\ninline void *operator new[](size_t, void *p) {\n return p;\n}\n#endif\n\nnamespace pxt {\n\ntemplate inline const T &max(const T &a, const T &b) {\n if (a < b)\n return b;\n return a;\n}\n\ntemplate inline const T &min(const T &a, const T &b) {\n if (a < b)\n return a;\n return b;\n}\n\ntemplate inline void swap(T &a, T &b) {\n T tmp = a;\n a = b;\n b = tmp;\n}\n\n//\n// Tagged values (assume 4 bytes for now, Cortex-M0)\n//\nstruct TValueStruct {};\ntypedef TValueStruct *TValue;\n\ntypedef TValue TNumber;\ntypedef TValue Action;\ntypedef TValue ImageLiteral;\n\n// To be implemented by the target\nextern \"C\" void target_panic(int error_code);\nextern \"C\" void target_reset();\nvoid sleep_ms(unsigned ms);\nvoid sleep_us(uint64_t us);\nvoid releaseFiber();\nuint64_t current_time_us();\nint current_time_ms();\nvoid initRuntime();\nvoid initSystemTimer();\nvoid sendSerial(const char *data, int len);\nvoid setSendToUART(void (*f)(const char *, int));\nuint64_t getLongSerialNumber();\nvoid registerWithDal(int id, int event, Action a, int flags = 16); // EVENT_LISTENER_DEFAULT_FLAGS\nvoid runInParallel(Action a);\nvoid runForever(Action a);\nvoid waitForEvent(int id, int event);\n//%\nunsigned afterProgramPage();\n//%\nvoid dumpDmesg();\nuint32_t hash_fnv1(const void *data, unsigned len);\n\n// also defined DMESG macro\n// end\n\n#define TAGGED_SPECIAL(n) (TValue)(void *)((n << 2) | 2)\n#define TAG_FALSE TAGGED_SPECIAL(2) // 10\n#define TAG_TRUE TAGGED_SPECIAL(16) // 66\n#define TAG_UNDEFINED (TValue)0\n#define TAG_NULL TAGGED_SPECIAL(1) // 6\n#define TAG_NAN TAGGED_SPECIAL(3) // 14\n#define TAG_NUMBER(n) (TNumber)(void *)(((uintptr_t)(uint32_t)(n) << 1) | 1)\n#define TAG_NON_VALUE TAGGED_SPECIAL(4) // 18; doesn't represent any JS value\n\n#ifdef PXT_VM\ninline bool isEncodedDouble(uint64_t v) {\n return (v >> 48) != 0;\n}\n#endif\n\ninline bool isDouble(TValue v) {\n#ifdef PXT64\n return ((uintptr_t)v >> 48) != 0;\n#else\n (void)v;\n return false;\n#endif\n}\n\ninline bool isPointer(TValue v) {\n return !isDouble(v) && v != 0 && ((intptr_t)v & 3) == 0;\n}\n\ninline bool isTagged(TValue v) {\n return (!isDouble(v) && ((intptr_t)v & 3)) || !v;\n}\n\ninline bool isInt(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 1);\n}\n\ninline bool isSpecial(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 2);\n}\n\ninline bool bothNumbers(TValue a, TValue b) {\n return !isDouble(a) && !isDouble(b) && ((intptr_t)a & (intptr_t)b & 1);\n}\n\ninline int numValue(TValue n) {\n return (int)((intptr_t)n >> 1);\n}\n\ninline bool canBeTagged(int v) {\n (void)v;\n#ifdef PXT_BOX_DEBUG\n return false;\n#elif defined(PXT64)\n return true;\n#else\n return (v << 1) >> 1 == v;\n#endif\n}\n\n// see https://anniecherkaev.com/the-secret-life-of-nan\n\n#define NanBoxingOffset 0x1000000000000LL\n\ntemplate TO bitwise_cast(FROM in) {\n STATIC_ASSERT(sizeof(TO) == sizeof(FROM));\n union {\n FROM from;\n TO to;\n } u;\n u.from = in;\n return u.to;\n}\n\ninline double decodeDouble(uint64_t v) {\n return bitwise_cast(v - NanBoxingOffset);\n}\n\n#ifdef PXT64\nSTATIC_ASSERT(sizeof(void *) == 8);\ninline double doubleVal(TValue v) {\n return bitwise_cast((uint64_t)v - NanBoxingOffset);\n}\n\ninline TValue tvalueFromDouble(double d) {\n return (TValue)(bitwise_cast(d) + NanBoxingOffset);\n}\n#else\nSTATIC_ASSERT(sizeof(void *) == 4);\n#endif\n\n// keep in sym with sim/control.ts\ntypedef enum {\n PANIC_CODAL_OOM = 20,\n PANIC_GC_OOM = 21,\n PANIC_GC_TOO_BIG_ALLOCATION = 22,\n PANIC_CODAL_HEAP_ERROR = 30,\n PANIC_CODAL_NULL_DEREFERENCE = 40,\n PANIC_CODAL_USB_ERROR = 50,\n PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n PANIC_INVALID_BINARY_HEADER = 901,\n PANIC_OUT_OF_BOUNDS = 902,\n PANIC_REF_DELETED = 903,\n PANIC_SIZE = 904,\n PANIC_INVALID_VTABLE = 905,\n PANIC_INTERNAL_ERROR = 906,\n PANIC_NO_SUCH_CONFIG = 907,\n PANIC_NO_SUCH_PIN = 908,\n PANIC_INVALID_ARGUMENT = 909,\n PANIC_MEMORY_LIMIT_EXCEEDED = 910,\n PANIC_SCREEN_ERROR = 911,\n PANIC_MISSING_PROPERTY = 912,\n PANIC_INVALID_IMAGE = 913,\n PANIC_CALLED_FROM_ISR = 914,\n PANIC_HEAP_DUMPED = 915,\n PANIC_STACK_OVERFLOW = 916,\n PANIC_BLOCKING_TO_STRING = 917,\n PANIC_VM_ERROR = 918,\n PANIC_SETTINGS_CLEARED = 920,\n PANIC_SETTINGS_OVERLOAD = 921,\n PANIC_SETTINGS_SECRET_MISSING = 922,\n PANIC_DELETE_ON_CLASS = 923,\n PANIC_OUT_OF_TIMERS = 924,\n PANIC_JACDAC = 925,\n PANIC_MICROPHONE_MISSING = 926,\n PANIC_VARIANT_NOT_SUPPORTED = 927,\n\n PANIC_CAST_FIRST = 980,\n PANIC_CAST_FROM_UNDEFINED = 980,\n PANIC_CAST_FROM_BOOLEAN = 981,\n PANIC_CAST_FROM_NUMBER = 982,\n PANIC_CAST_FROM_STRING = 983,\n PANIC_CAST_FROM_OBJECT = 984,\n PANIC_CAST_FROM_FUNCTION = 985,\n PANIC_CAST_FROM_NULL = 989,\n\n PANIC_UNHANDLED_EXCEPTION = 999,\n\n} PXT_PANIC;\n\nextern const uintptr_t functionsAndBytecode[];\nextern TValue *globals;\nextern uint16_t *bytecode;\nclass RefRecord;\n\n// Utility functions\n\ntypedef TValue (*RunActionType)(Action a, TValue arg0, TValue arg1, TValue arg2);\n\n#define asmRunAction3 ((RunActionType)(((uintptr_t *)bytecode)[12]))\n\nstatic inline TValue runAction3(Action a, TValue arg0, TValue arg1, TValue arg2) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction2(Action a, TValue arg0, TValue arg1) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction1(Action a, TValue arg0) {\n return asmRunAction3(a, arg0, 0, 0);\n}\nstatic inline TValue runAction0(Action a) {\n return asmRunAction3(a, 0, 0, 0);\n}\n\nclass RefAction;\nclass BoxedString;\nstruct VTable;\n\n//%\nAction mkAction(int totallen, RefAction *act);\n//% expose\nint templateHash();\n//% expose\nint programHash();\n//% expose\nBoxedString *programName();\n//% expose\nunsigned programSize();\n//%\nint getNumGlobals();\n//%\nRefRecord *mkClassInstance(VTable *vt);\n//%\nvoid debugMemLeaks();\n//%\nvoid anyPrint(TValue v);\n\n//%\nint getConfig(int key, int defl = -1);\n\n//%\nint toInt(TNumber v);\n//%\nunsigned toUInt(TNumber v);\n//%\nNUMBER toDouble(TNumber v);\n//%\nfloat toFloat(TNumber v);\n//%\nTNumber fromDouble(NUMBER r);\n//%\nTNumber fromFloat(float r);\n\n//%\nTNumber fromInt(int v);\n//%\nTNumber fromUInt(unsigned v);\n//%\nTValue fromBool(bool v);\n//%\nbool eq_bool(TValue a, TValue b);\n//%\nbool eqq_bool(TValue a, TValue b);\n\n//%\nvoid failedCast(TValue v, void *addr = NULL);\n//%\nvoid missingProperty(TValue v);\n\nvoid error(PXT_PANIC code, int subcode = 0);\nvoid exec_binary(unsigned *pc);\nvoid start();\n\nstruct HandlerBinding {\n HandlerBinding *next;\n int source;\n int value;\n Action action;\n#ifndef PXT_CODAL\n uint32_t flags;\n struct Event *pending;\n#endif\n};\nHandlerBinding *findBinding(int source, int value);\nHandlerBinding *nextBinding(HandlerBinding *curr, int source, int value);\nvoid setBinding(int source, int value, Action act);\n\n// Legacy stuff; should no longer be used\n//%\nTValue incr(TValue e);\n//%\nvoid decr(TValue e);\n\ninline TValue incr(TValue e) {\n return e;\n}\ninline void decr(TValue e) {}\n\nclass RefObject;\n\nstatic inline RefObject *incrRC(RefObject *r) {\n return r;\n}\nstatic inline void decrRC(RefObject *) {}\n\ninline void *ptrOfLiteral(int offset) {\n return &bytecode[offset];\n}\n\n// Checks if object is ref-counted, and has a custom PXT vtable in front\n// TODO\ninline bool isRefCounted(TValue e) {\n return isPointer(e);\n}\n\ninline void check(int cond, PXT_PANIC code, int subcode = 0) {\n if (!cond)\n error(code, subcode);\n}\n\ninline void oops(int subcode = 0) {\n target_panic(800 + subcode);\n}\n\nclass RefObject;\n\ntypedef void (*RefObjectMethod)(RefObject *self);\ntypedef unsigned (*RefObjectSizeMethod)(RefObject *self);\ntypedef void *PVoid;\ntypedef void **PPVoid;\n\ntypedef void *Object_;\n\n#define VTABLE_MAGIC 0xF9\n#define VTABLE_MAGIC2 0xF8\n\nenum class ValType : uint8_t {\n Undefined,\n Boolean,\n Number,\n String,\n Object,\n Function,\n};\n\n// keep in sync with pxt-core (search for the type name)\nenum class BuiltInType : uint16_t {\n BoxedString = 1,\n BoxedNumber = 2,\n BoxedBuffer = 3,\n RefAction = 4,\n RefImage = 5,\n RefCollection = 6,\n RefRefLocal = 7,\n RefMap = 8,\n RefMImage = 9, // microbit-specific\n MMap = 10, // linux, mostly ev3\n BoxedString_SkipList = 11, // used by VM bytecode representation only\n BoxedString_ASCII = 12, // ditto\n ZPin = 13,\n User0 = 16,\n};\n\nstruct VTable {\n uint16_t numbytes;\n ValType objectType;\n uint8_t magic;\n#ifdef PXT_VM\n uint16_t ifaceHashEntries;\n BuiltInType lastClassNo;\n#else\n PVoid *ifaceTable;\n#endif\n BuiltInType classNo;\n uint16_t reserved;\n uint32_t ifaceHashMult;\n\n // we only use the first few methods here; pxt will generate more\n PVoid methods[8];\n};\n\n//%\nextern const VTable string_inline_ascii_vt;\n#if PXT_UTF8\n//%\nextern const VTable string_inline_utf8_vt;\n//%\nextern const VTable string_cons_vt;\n//%\nextern const VTable string_skiplist16_vt;\n//%\nextern const VTable string_skiplist16_packed_vt;\n#endif\n//%\nextern const VTable buffer_vt;\n//%\nextern const VTable number_vt;\n//%\nextern const VTable RefAction_vtable;\n\n#ifndef PXT_IS_READONLY\n// assume ARM - ram addresses are 0x2000_0000+; flash is either 0x0+ or 0x0800_0000+\n#define PXT_IS_READONLY(v) (isTagged(v) || !((uintptr_t)v >> 28))\n#endif\n\ninline bool isReadOnly(TValue v) {\n return PXT_IS_READONLY(v);\n}\n\n// A base abstract class for ref-counted objects.\nclass RefObject {\n public:\n const VTable *vtable;\n\n RefObject(const VTable *vt) {\n#if defined(PXT32) && defined(PXT_VM) && !defined(PXT_ESP32)\n if ((uint32_t)vt & 0xf0000000)\n target_panic(PANIC_INVALID_VTABLE);\n#endif\n vtable = vt;\n }\n\n void destroyVT();\n void printVT();\n\n inline uintptr_t vt() { return (uintptr_t)vtable; }\n inline void setVT(uintptr_t v) { vtable = (const VTable *)v; }\n\n inline void ref() {}\n inline void unref() {}\n inline bool isReadOnly() { return pxt::isReadOnly((TValue)this); }\n};\n\nclass Segment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n // this just gives max value of ramint_t\n void growByMin(ramint_t minSize);\n void ensure(ramint_t newSize);\n\n public:\n static constexpr ramint_t MaxSize = (((1U << (8 * sizeof(ramint_t) - 1)) - 1) << 1) + 1;\n static constexpr TValue DefaultValue = TAG_UNDEFINED; // == NULL\n\n Segment() : data(nullptr), length(0), size(0) {}\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n void set(unsigned i, TValue value);\n\n unsigned getLength() { return length; };\n void setLength(unsigned newLength);\n\n void push(TValue value) { set(length, value); }\n TValue pop();\n\n TValue remove(unsigned i);\n void insert(unsigned i, TValue value);\n\n void destroy();\n\n void print();\n\n TValue *getData() { return data; }\n};\n\n// Low-Level segment using system malloc\nclass LLSegment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n public:\n LLSegment() : data(nullptr), length(0), size(0) {}\n\n void set(unsigned idx, TValue v);\n void push(TValue value) { set(length, value); }\n TValue pop();\n void destroy();\n void setLength(unsigned newLen);\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n unsigned getLength() { return length; };\n TValue *getData() { return data; }\n};\n\n// A ref-counted collection of either primitive or ref-counted objects (String, Image,\n// user-defined record, another collection)\nclass RefCollection : public RefObject {\n public:\n Segment head;\n\n RefCollection();\n\n static void destroy(RefCollection *coll);\n static void scan(RefCollection *coll);\n static unsigned gcsize(RefCollection *coll);\n static void print(RefCollection *coll);\n\n unsigned length() { return head.getLength(); }\n void setLength(unsigned newLength) { head.setLength(newLength); }\n TValue getAt(int i) { return head.get(i); }\n TValue *getData() { return head.getData(); }\n};\n\nclass RefMap : public RefObject {\n public:\n Segment keys;\n Segment values;\n\n RefMap();\n static void destroy(RefMap *map);\n static void scan(RefMap *map);\n static unsigned gcsize(RefMap *coll);\n static void print(RefMap *map);\n int findIdx(BoxedString *key);\n};\n\n// A ref-counted, user-defined JS object.\nclass RefRecord : public RefObject {\n public:\n // The object is allocated, so that there is space at the end for the fields.\n TValue fields[];\n\n RefRecord(VTable *v) : RefObject(v) {}\n\n TValue ld(int idx);\n TValue ldref(int idx);\n void st(int idx, TValue v);\n void stref(int idx, TValue v);\n};\n\nstatic inline VTable *getVTable(RefObject *r) {\n return (VTable *)(r->vt() & ~1);\n}\n\nstatic inline VTable *getAnyVTable(TValue v) {\n if (!isRefCounted(v))\n return NULL;\n auto vt = getVTable((RefObject *)v);\n if (vt->magic == VTABLE_MAGIC)\n return vt;\n return NULL;\n}\n\n// these are needed when constructing vtables for user-defined classes\n//%\nvoid RefRecord_destroy(RefRecord *r);\n//%\nvoid RefRecord_print(RefRecord *r);\n//%\nvoid RefRecord_scan(RefRecord *r);\n//%\nunsigned RefRecord_gcsize(RefRecord *r);\n\ntypedef TValue (*ActionCB)(TValue *captured, TValue arg0, TValue arg1, TValue arg2);\n\n// Ref-counted function pointer.\nclass RefAction : public RefObject {\n public:\n uint16_t len;\n uint16_t numArgs;\n#ifdef PXT_VM\n uint16_t initialLen;\n uint16_t flags;\n uintptr_t func;\n#else\n ActionCB func; // The function pointer\n#endif\n // fields[] contain captured locals\n TValue fields[];\n\n static void destroy(RefAction *act);\n static void scan(RefAction *act);\n static unsigned gcsize(RefAction *coll);\n static void print(RefAction *act);\n\n RefAction();\n\n inline void stCore(int idx, TValue v) {\n // DMESG(\"ST [%d] = %d \", idx, v); this->print();\n intcheck(0 <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 10);\n intcheck(fields[idx] == 0, PANIC_OUT_OF_BOUNDS, 11); // only one assignment permitted\n fields[idx] = v;\n }\n};\n\n// These two are used to represent locals written from inside inline functions\nclass RefRefLocal : public RefObject {\n public:\n TValue v;\n static void destroy(RefRefLocal *l);\n static void scan(RefRefLocal *l);\n static unsigned gcsize(RefRefLocal *l);\n static void print(RefRefLocal *l);\n RefRefLocal();\n};\n\ntypedef int color;\n\n// note: this is hardcoded in PXT (hexfile.ts)\n\nclass BoxedNumber : public RefObject {\n public:\n NUMBER num;\n BoxedNumber() : RefObject(&number_vt) {}\n} __attribute__((packed));\n\nclass BoxedString : public RefObject {\n public:\n union {\n struct {\n uint16_t length; // ==size\n char data[0];\n } ascii;\n#if PXT_UTF8\n struct {\n uint16_t size;\n char data[0];\n } utf8;\n struct {\n BoxedString *left;\n BoxedString *right;\n } cons;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t *list;\n } skip;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t list[0];\n } skip_pack;\n#endif\n };\n\n#if PXT_UTF8\n uintptr_t runMethod(int idx) {\n return ((uintptr_t(*)(BoxedString *))vtable->methods[idx])(this);\n }\n const char *getUTF8Data() { return (const char *)runMethod(4); }\n uint32_t getUTF8Size() { return (uint32_t)runMethod(5); }\n // in characters\n uint32_t getLength() { return (uint32_t)runMethod(6); }\n const char *getUTF8DataAt(uint32_t pos) {\n auto meth = ((const char *(*)(BoxedString *, uint32_t))vtable->methods[7]);\n return meth(this, pos);\n }\n#else\n const char *getUTF8Data() { return ascii.data; }\n uint32_t getUTF8Size() { return ascii.length; }\n uint32_t getLength() { return ascii.length; }\n const char *getUTF8DataAt(uint32_t pos) { return pos < ascii.length ? ascii.data + pos : NULL; }\n#endif\n\n TNumber charCodeAt(int pos);\n\n BoxedString(const VTable *vt) : RefObject(vt) {}\n};\n\n// cross version compatible way of accessing string data\n#ifndef PXT_STRING_DATA\n#define PXT_STRING_DATA(str) str->getUTF8Data()\n#endif\n\n// cross version compatible way of accessing string length\n#ifndef PXT_STRING_DATA_LENGTH\n#define PXT_STRING_DATA_LENGTH(str) str->getUTF8Size()\n#endif\n\nclass BoxedBuffer : public RefObject {\n public:\n // data needs to be word-aligned, so we use 32 bits for length\n int length;\n uint8_t data[0];\n BoxedBuffer() : RefObject(&buffer_vt) {}\n\n static bool isInstance(TValue v);\n};\n\n// cross version compatible way of access data field\n#ifndef PXT_BUFFER_DATA\n#define PXT_BUFFER_DATA(buffer) buffer->data\n#endif\n\n// cross version compatible way of access data length\n#ifndef PXT_BUFFER_LENGTH\n#define PXT_BUFFER_LENGTH(buffer) buffer->length\n#endif\n\n#ifndef PXT_CREATE_BUFFER\n#define PXT_CREATE_BUFFER(data, len) pxt::mkBuffer(data, len)\n#endif\n\n// Legacy format:\n// the first byte of data indicates the format - currently 0xE1 or 0xE4 to 1 or 4 bit bitmaps\n// second byte indicates width in pixels\n// third byte indicates the height (which should also match the size of the buffer)\n// just like ordinary buffers, these can be layed out in flash\n\n// Current format:\n// 87 BB WW WW HH HH 00 00 DATA\n// that is: 0x87, 0x01 or 0x04 - bpp, width in little endian, height, 0x00, 0x00 followed by data\n// for 4 bpp images, rows are word-aligned (as in legacy)\n\n#define IMAGE_HEADER_MAGIC 0x87\n\nstruct ImageHeader {\n uint8_t magic;\n uint8_t bpp;\n uint16_t width;\n uint16_t height;\n uint16_t padding;\n uint8_t pixels[0];\n};\n\nclass RefImage : public RefObject {\n public:\n BoxedBuffer *buffer;\n uint32_t revision;\n\n RefImage(BoxedBuffer *buf);\n RefImage(uint32_t sz);\n\n void setBuffer(BoxedBuffer *b);\n\n uint8_t *data() { return buffer->data; }\n int length() { return (int)buffer->length; }\n\n ImageHeader *header() { return (ImageHeader *)buffer->data; }\n int pixLength() { return length() - sizeof(ImageHeader); }\n\n int width() { return header()->width; }\n int height() { return header()->height; }\n int wordHeight();\n int bpp() { return header()->bpp; }\n\n bool hasPadding() { return (height() & 0x7) != 0; }\n\n uint8_t *pix() { return header()->pixels; }\n\n int byteHeight() {\n if (bpp() == 1)\n return (height() + 7) >> 3;\n else if (bpp() == 4)\n return ((height() * 4 + 31) >> 5) << 2;\n else {\n oops(21);\n return -1;\n }\n }\n\n uint8_t *pix(int x, int y) {\n uint8_t *d = &pix()[byteHeight() * x];\n if (y) {\n if (bpp() == 1)\n d += y >> 3;\n else if (bpp() == 4)\n d += y >> 1;\n }\n return d;\n }\n\n uint8_t fillMask(color c);\n bool inRange(int x, int y);\n void clamp(int *x, int *y);\n void makeWritable();\n\n static void destroy(RefImage *t);\n static void scan(RefImage *t);\n static unsigned gcsize(RefImage *t);\n static void print(RefImage *t);\n};\n\nRefImage *mkImage(int w, int h, int bpp);\n\ntypedef BoxedBuffer *Buffer;\ntypedef BoxedString *String;\ntypedef RefImage *Image_;\n\nuint32_t toRealUTF8(String str, uint8_t *dst);\n\n// keep in sync with github/pxt/pxtsim/libgeneric.ts\nenum class NumberFormat {\n Int8LE = 1,\n UInt8LE,\n Int16LE,\n UInt16LE,\n Int32LE,\n Int8BE,\n UInt8BE,\n Int16BE,\n UInt16BE,\n Int32BE,\n\n UInt32LE,\n UInt32BE,\n Float32LE,\n Float64LE,\n Float32BE,\n Float64BE,\n};\n\n// this will, unlike mkStringCore, UTF8-canonicalize the data\nString mkString(const char *data, int len = -1);\n// data can be NULL in both cases\nBuffer mkBuffer(const void *data, int len);\nString mkStringCore(const char *data, int len = -1);\n\nTNumber getNumberCore(uint8_t *buf, int size, NumberFormat format);\nvoid setNumberCore(uint8_t *buf, int size, NumberFormat format, TNumber value);\n\nvoid seedRandom(unsigned seed);\nvoid seedAddRandom(unsigned seed);\n// max is inclusive\nunsigned getRandom(unsigned max);\n\nValType valType(TValue v);\n\n// this is equivalent to JS `throw v`; it will leave\n// the current function(s), all the way until the nearest try block and\n// ignore all destructors (think longjmp())\nvoid throwValue(TValue v);\n\nvoid registerGC(TValue *root, int numwords = 1);\nvoid unregisterGC(TValue *root, int numwords = 1);\nvoid registerGCPtr(TValue ptr);\nvoid unregisterGCPtr(TValue ptr);\nstatic inline void registerGCObj(RefObject *ptr) {\n registerGCPtr((TValue)ptr);\n}\nstatic inline void unregisterGCObj(RefObject *ptr) {\n unregisterGCPtr((TValue)ptr);\n}\nvoid gc(int flags);\n\nstruct StackSegment {\n void *top;\n void *bottom;\n StackSegment *next;\n};\n\n#define NUM_TRY_FRAME_REGS 3\nstruct TryFrame {\n TryFrame *parent;\n uintptr_t registers[NUM_TRY_FRAME_REGS];\n};\n\nstruct ThreadContext {\n TValue *globals;\n StackSegment stack;\n TryFrame *tryFrame;\n TValue thrownValue;\n#ifdef PXT_GC_THREAD_LIST\n ThreadContext *next;\n ThreadContext *prev;\n#endif\n};\n\n#ifdef PXT_GC_THREAD_LIST\nextern ThreadContext *threadContexts;\nvoid *threadAddressFor(ThreadContext *, void *sp);\n#endif\n\nvoid releaseThreadContext(ThreadContext *ctx);\nThreadContext *getThreadContext();\nvoid setThreadContext(ThreadContext *ctx);\n\n#ifndef PXT_GC_THREAD_LIST\nvoid gcProcessStacks(int flags);\n#endif\n\nvoid gcProcess(TValue v);\nvoid gcFreeze();\n\n#ifdef PXT_VM\nvoid gcStartup();\nvoid gcPreStartup();\n#endif\n\nvoid coreReset();\nvoid gcReset();\nvoid systemReset();\n\nvoid doNothing();\n\nvoid *gcAllocate(int numbytes);\nvoid *gcAllocateArray(int numbytes);\nextern \"C\" void *app_alloc(int numbytes);\nextern \"C\" void *app_free(void *ptr);\nextern \"C\" void *app_alloc_at(void *at, int numbytes);\nvoid gcPreAllocateBlock(uint32_t sz);\n\nint redirectSamples(int16_t *dst, int numsamples, int samplerate);\n\n#ifdef PXT64\n#define TOWORDS(bytes) (((bytes) + 7) >> 3)\n#else\n#define TOWORDS(bytes) (((bytes) + 3) >> 2)\n#endif\n\n#ifndef PXT_VM\n#define soft_panic target_panic\n#endif\n\nextern int debugFlags;\n\nenum class PerfCounters {\n GC,\n};\n\n#ifdef PXT_PROFILE\n#ifndef PERF_NOW\n#error \"missing platform timer support\"\n#endif\n\nstruct PerfCounter {\n uint32_t value;\n uint32_t numstops;\n uint32_t start;\n};\n\nextern struct PerfCounter *perfCounters;\n\nvoid initPerfCounters();\n//%\nvoid dumpPerfCounters();\n//%\nvoid startPerfCounter(PerfCounters n);\n//%\nvoid stopPerfCounter(PerfCounters n);\n#else\ninline void startPerfCounter(PerfCounters n) {}\ninline void stopPerfCounter(PerfCounters n) {}\ninline void initPerfCounters() {}\ninline void dumpPerfCounters() {}\n#endif\n\n// Handling of built-in string literals (like \"[Object]\", \"true\" etc.).\n\n// This has the same layout as BoxedString, but has statically allocated buffer\ntemplate struct BoxedStringLayout {\n const void *vtable;\n uint16_t size;\n const char data[N];\n};\n\ntemplate constexpr size_t _boxedStringLen(char const (&)[N]) {\n return N;\n}\n\n// strings defined here as used as (String)name\n#define PXT_DEF_STRING(name, val) \\\n const BoxedStringLayout<_boxedStringLen(val)> name[1] = { \\\n {&pxt::string_inline_ascii_vt, _boxedStringLen(val) - 1, val}};\n\n// bigger value - less memory, but slower\n// 16/20 keeps s.length and s.charCodeAt(i) at about 200 cycles (for actual unicode strings),\n// which is similar to amortized allocation time\n#define PXT_STRING_SKIP_INCR 16 // needs to be power of 2; needs to be kept in sync with compiler\n#define PXT_STRING_MIN_SKIP \\\n 20 // min. size of string to use skip list; static code has its own limit\n\n#define PXT_NUM_SKIP_ENTRIES(p) ((p)->skip.length / PXT_STRING_SKIP_INCR)\n#define PXT_SKIP_DATA_IND(p) ((const char *)(p->skip.list + PXT_NUM_SKIP_ENTRIES(p)))\n#define PXT_SKIP_DATA_PACK(p) ((const char *)(p->skip_pack.list + PXT_NUM_SKIP_ENTRIES(p)))\n\n} // namespace pxt\n\nusing namespace pxt;\n\nnamespace numops {\n//%\nString toString(TValue v);\n//%\nint toBool(TValue v);\n//%\nint toBoolDecr(TValue v);\n} // namespace numops\n\nnamespace pxt {\ninline bool toBoolQuick(TValue v) {\n if (v == TAG_TRUE)\n return true;\n if (v == TAG_FALSE || v == TAG_UNDEFINED || v == TAG_NULL)\n return false;\n return numops::toBool(v);\n}\n} // namespace pxt\n\nnamespace pxtrt {\n//%\nRefMap *mkMap();\n//%\nTValue mapGetByString(RefMap *map, String key);\n//%\nint lookupMapKey(String key);\n//%\nTValue mapGet(RefMap *map, unsigned key);\n//% expose\nvoid mapSetByString(RefMap *map, String key, TValue val);\n//%\nvoid mapSet(RefMap *map, unsigned key, TValue val);\n} // namespace pxtrt\n\nnamespace pins {\nBuffer createBuffer(int size);\n}\n\nnamespace String_ {\n//%\nint compare(String a, String b);\n} // namespace String_\n\nnamespace Array_ {\n//%\nRefCollection *mk();\n//%\nint length(RefCollection *c);\n//%\nvoid setLength(RefCollection *c, int newLength);\n//%\nvoid push(RefCollection *c, TValue x);\n//%\nTValue pop(RefCollection *c);\n//%\nTValue getAt(RefCollection *c, int x);\n//%\nvoid setAt(RefCollection *c, int x, TValue y);\n//%\nTValue removeAt(RefCollection *c, int x);\n//%\nvoid insertAt(RefCollection *c, int x, TValue value);\n//%\nint indexOf(RefCollection *c, TValue x, int start);\n//%\nbool removeElement(RefCollection *c, TValue x);\n} // namespace Array_\n\n#define NEW_GC(T, ...) new (gcAllocate(sizeof(T))) T(__VA_ARGS__)\n\n// The ARM Thumb generator in the JavaScript code is parsing\n// the hex file and looks for the magic numbers as present here.\n//\n// Then it fetches function pointer addresses from there.\n//\n// The vtable pointers are there, so that the ::emptyData for various types\n// can be patched with the right vtable.\n//\n#define PXT_SHIMS_BEGIN \\\n namespace pxt { \\\n const uintptr_t functionsAndBytecode[] \\\n __attribute__((aligned(0x20))) = {0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,\n\n#define PXT_SHIMS_END \\\n } \\\n ; \\\n }\n\n#if !defined(X86_64) && !defined(PXT_VM)\n#pragma GCC diagnostic ignored \"-Wpmf-conversions\"\n#endif\n\n#ifdef PXT_VM\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#else\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#endif\n\n#define PXT_VTABLE(classname, valtp) \\\n DEF_VTABLE(classname##_vtable, classname, valtp, (void *)&classname::destroy, \\\n (void *)&classname::print, (void *)&classname::scan, (void *)&classname::gcsize)\n\n#define PXT_EXT_VTABLE(classname) \\\n static int classname##_gcsize() { return sizeof(classname); } \\\n DEF_VTABLE_EXT(classname##_vtable, classname, ValType::Object, (void *)&pxt::doNothing, \\\n (void *)&pxt::anyPrint, (void *)&pxt::doNothing, (void *)&classname##_gcsize)\n\n#define PXT_VTABLE_INIT(classname) RefObject(&classname##_vtable)\n\n#define PXT_VTABLE_CTOR(classname) \\\n PXT_VTABLE(classname, ValType::Object) \\\n classname::classname() : PXT_VTABLE_INIT(classname)\n\n#define PXT_MAIN \\\n int main() { \\\n pxt::start(); \\\n return 0; \\\n }\n\n#define PXT_FNPTR(x) (uintptr_t)(void *)(x)\n\n#define PXT_ABI(...)\n\n#define JOIN(a, b) a##b\n/// Defines getClassName() function to fetch the singleton\n#define SINGLETON(ClassName) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n/// Defines getClassName() function to fetch the singleton if PIN present\n#define SINGLETON_IF_PIN(ClassName, pin) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName) && LOOKUP_PIN(pin)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n#ifdef PXT_VM\n#include \"vm.h\"\n#endif\n\n#endif\n", "scheduling.ts": "/**\n * Calls a function with a fixed time delay between each call to that function.\n * @param func \n * @param delay \n */\n//%\nfunction setInterval(func: () => void, delay: number): number {\n delay = Math.max(10, delay | 0);\n return control.setInterval(func, delay, control.IntervalMode.Interval);\n}\n\n/**\n * Cancels repeated action which was set up using setInterval().\n * @param intervalId \n */\n//%\nfunction clearInterval(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Interval);\n}\n\n/**\n * Calls a function after specified delay.\n * @param func \n * @param delay \n */\n//%\nfunction setTimeout(func: () => void, delay: number): number {\n return control.setInterval(func, delay, control.IntervalMode.Timeout);\n}\n\n/**\n * Clears the delay set by setTimeout().\n * @param intervalId \n */\n//%\nfunction clearTimeout(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Timeout);\n}\n\n/**\n * Calls a function as soon as possible.\n * @param func \n */\n//%\nfunction setImmediate(func: () => void): number {\n return control.setInterval(func, 0, control.IntervalMode.Immediate);\n}\n\n/**\n * Cancels the immediate actions.\n * @param intervalId \n */\n//%\nfunction clearImmediate(intervalId: number) {\n control.clearInterval(intervalId, control.IntervalMode.Immediate);\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\ndeclare interface Buffer {\n /**\n * Reads an unsigned byte at a particular location\n */\n //% shim=BufferMethods::getUint8\n getUint8(off: int32): int32;\n\n /**\n * Returns false when the buffer can be written to.\n */\n //% shim=BufferMethods::isReadOnly\n isReadOnly(): boolean;\n\n /**\n * Writes an unsigned byte at a particular location\n */\n //% shim=BufferMethods::setUint8\n setUint8(off: int32, v: int32): void;\n\n /**\n * Write a number in specified format in the buffer.\n */\n //% shim=BufferMethods::setNumber\n setNumber(format: NumberFormat, offset: int32, value: number): void;\n\n /**\n * Read a number in specified format from the buffer.\n */\n //% shim=BufferMethods::getNumber\n getNumber(format: NumberFormat, offset: int32): number;\n\n /** Returns the length of a Buffer object. */\n //% property shim=BufferMethods::length\n length: int32;\n\n /**\n * Fill (a fragment) of the buffer with given value.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::fill\n fill(value: int32, offset?: int32, length?: int32): void;\n\n /**\n * Return a copy of a fragment of a buffer.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::slice\n slice(offset?: int32, length?: int32): Buffer;\n\n /**\n * Shift buffer left in place, with zero padding.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus\n * start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::shift\n shift(offset: int32, start?: int32, length?: int32): void;\n\n /**\n * Convert a buffer to string assuming UTF8 encoding\n */\n //% shim=BufferMethods::toString\n toString(): string;\n\n /**\n * Convert a buffer to its hexadecimal representation.\n */\n //% shim=BufferMethods::toHex\n toHex(): string;\n\n /**\n * Rotate buffer left in place.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus\n * start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::rotate\n rotate(offset: int32, start?: int32, length?: int32): void;\n\n /**\n * Write contents of `src` at `dstOffset` in current buffer.\n */\n //% shim=BufferMethods::write\n write(dstOffset: int32, src: Buffer): void;\n\n /**\n * Compute k-bit FNV-1 non-cryptographic hash of the buffer.\n */\n //% shim=BufferMethods::hash\n hash(bits: int32): uint32;\n}\ndeclare namespace control {\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% deprecated=1 shim=control::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Create a new buffer with UTF8-encoded string\n * @param str the string to put in the buffer\n */\n //% deprecated=1 shim=control::createBufferFromUTF8\n function createBufferFromUTF8(str: string): Buffer;\n}\ndeclare namespace loops {\n\n /**\n * Repeats the code forever in the background. On each iteration, allows other codes to run.\n * @param body code to execute\n */\n //% help=loops/forever weight=100 afterOnStart=true deprecated=true\n //% blockId=forever_deprecated block=\"forever\" blockAllowMultiple=1 shim=loops::forever\n function forever(a: () => void): void;\n\n /**\n * Pause for the specified time in milliseconds\n * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000\n */\n //% help=loops/pause weight=99 deprecated=true\n //% async block=\"pause %pause=timePicker|ms\"\n //% blockId=device_pause_deprecated shim=loops::pause\n function pause(ms: int32): void;\n}\ndeclare namespace control {\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=control/millis weight=50\n //% blockId=control_running_time block=\"millis (ms)\" shim=control::millis\n function millis(): int32;\n\n /**\n * Gets current time in microseconds. Overflows every ~18 minutes.\n */\n //% shim=control::micros\n function micros(): int32;\n\n /**\n * Used internally\n */\n //% flags.defl=16 shim=control::internalOnEvent\n function internalOnEvent(src: int32, value: int32, handler: () => void, flags?: int32): void;\n\n /**\n * Reset the device.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\" shim=control::reset\n function reset(): void;\n\n /**\n * Block the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29 async\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\" shim=control::waitMicros\n function waitMicros(micros: int32): void;\n\n /**\n * Run other code in the parallel.\n */\n //% help=control/run-in-parallel handlerStatement=1\n //% blockId=\"control_run_in_parallel\" block=\"run in parallel\" blockGap=8 shim=control::runInParallel\n function runInParallel(a: () => void): void;\n\n /**\n * Blocks the calling thread until the specified event is raised.\n */\n //% help=control/wait-for-event async\n //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\" shim=control::waitForEvent\n function waitForEvent(src: int32, value: int32): void;\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9\n //% help=control/device-serial-number shim=control::deviceSerialNumber\n function deviceSerialNumber(): int32;\n\n /**\n * Derive a unique, consistent 64-bit serial number of this device from internal data.\n */\n //% blockId=\"control_device_long_serial_number\" block=\"device long serial number\" weight=9\n //% help=control/device-long-serial-number shim=control::deviceLongSerialNumber\n function deviceLongSerialNumber(): Buffer;\n\n /**\n *\n */\n //% shim=control::__log\n function __log(prority: int32, text: string): void;\n\n /**\n * Dump internal information about a value.\n */\n //% shim=control::dmesgValue\n function dmesgValue(v: any): void;\n}\ndeclare namespace control {\n\n /**\n * Force GC and dump basic information about heap.\n */\n //% shim=control::gc\n function gc(): void;\n\n /**\n * Force GC and halt waiting for debugger to do a full heap dump.\n */\n //% shim=control::heapDump\n function heapDump(): void;\n\n /**\n * Set flags used when connecting an external debugger.\n */\n //% shim=control::setDebugFlags\n function setDebugFlags(flags: int32): void;\n\n /**\n * Record a heap snapshot to debug memory leaks.\n */\n //% shim=control::heapSnapshot\n function heapSnapshot(): void;\n\n /**\n * Return true if profiling is enabled in the current build.\n */\n //% shim=control::profilingEnabled\n function profilingEnabled(): boolean;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -689,7 +690,7 @@ "platform.cpp": "#include \"pxt.h\"\n#include \"light.h\"\n\nnamespace pxt {\n\nCODAL_TIMER devTimer;\n\nstatic void initRandomSeed() {\n int seed = 0xC0DA1;\n auto pinTemp = LOOKUP_PIN(TEMPERATURE);\n if (pinTemp)\n seed *= pinTemp->getAnalogValue();\n auto pinLight = LOOKUP_PIN(LIGHT);\n if (pinLight)\n seed *= pinLight->getAnalogValue();\n seedRandom(seed);\n}\n\nstatic void remapSwdPin(int pinCfg, int fallback) {\n int pinName = getConfig(pinCfg);\n if (pinName == PA30 || pinName == PA31) {\n if (getConfig(CFG_SWD_ENABLED, 0)) {\n linkPin(pinName, fallback);\n } else {\n PORT->Group[pinName / 32].PINCFG[pinName % 32].reg = (uint8_t)PORT_PINCFG_INEN;\n }\n }\n}\n\nstatic void initSwdPins() {\n remapSwdPin(CFG_PIN_NEOPIXEL, PIN(D0));\n remapSwdPin(CFG_PIN_RXLED, PIN(D1));\n remapSwdPin(CFG_PIN_SPEAKER_AMP, PIN(D2));\n}\n\nvoid platform_init() {\n initSwdPins();\n initRandomSeed();\n light::clear();\n\n if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n *HF2_DBG_MAGIC_PTR = 0;\n // this will cause alignment fault at the first breakpoint\n globals[0] = (TValue)1;\n }\n}\n\n} // namespace pxt\n", "platform.h": "#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n// This is specific for SAMD21, to be replaced in other Codal targets.\n\n#include \"CapTouchButton.h\"\n#include \"Image.h\"\n#include \"MbedTimer.h\"\n#include \"MbedI2C.h\"\n#include \"MbedPin.h\"\n#include \"MbedSPI.h\"\n#include \"MbedSerial.h\"\n#include \"MultiButton.h\"\n#include \"CPlayI2C.h\"\n\n#include \"SAMD21DMAC.h\"\n\n// Analog Pins, all SAMD21: PA02-PA11 PB00-PB09 (some pins not connected)\n// 2 ports times 32 pins in each\n#define DEV_NUM_PINS 64\n// pins marked with AIN and PTC in the data sheet\n#define DEV_ANALOG_PINS 0x3ff00000ffcULL\n\n#define PAGE_SIZE 256\n\n#define CODAL_DMAC SAMD21DMAC\n\n// this is codal::_mbed for both mbed and mbedos now\n#define CODAL_MBED codal::_mbed\n\n#define CODAL_I2C codal::CPlayI2C\n\n#ifndef IMAGE_BITS\n#define IMAGE_BITS 1\n#endif\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n#define PA00 0\n#define PA01 1\n#define PA02 2\n#define PA03 3\n#define PA04 4\n#define PA05 5\n#define PA06 6\n#define PA07 7\n#define PA08 8\n#define PA09 9\n#define PA10 10\n#define PA11 11\n#define PA12 12\n#define PA13 13\n#define PA14 14\n#define PA15 15\n#define PA16 16\n#define PA17 17\n#define PA18 18\n#define PA19 19\n#define PA20 20\n#define PA21 21\n#define PA22 22\n#define PA23 23\n#define PA24 24\n#define PA25 25\n#define PA26 26\n#define PA27 27\n#define PA28 28\n#define PA29 29\n#define PA30 30\n#define PA31 31\n#define PB00 32\n#define PB01 33\n#define PB02 34\n#define PB03 35\n#define PB04 36\n#define PB05 37\n#define PB06 38\n#define PB07 39\n#define PB08 40\n#define PB09 41\n#define PB10 42\n#define PB11 43\n#define PB12 44\n#define PB13 45\n#define PB14 46\n#define PB15 47\n#define PB16 48\n#define PB17 49\n#define PB18 50\n#define PB19 51\n#define PB20 52\n#define PB21 53\n#define PB22 54\n#define PB23 55\n#define PB24 56\n#define PB25 57\n#define PB26 58\n#define PB27 59\n#define PB28 60\n#define PB29 61\n#define PB30 62\n#define PB31 63\n#endif\n\n#endif\n", "pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n", - "pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", "pxtcore.h": "#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n", "pxtparts.json": "{\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 19,\n \"y\": 0\n },\n {\n \"x\": 28,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"dotstar\": {\n \"simulationBehavior\": \"dotstar\",\n \"visual\": {\n \"builtIn\": \"dotstar\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 1\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createAPA102Strip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"dataPin\"\n },\n {\n \"pinInstantiationIdx\": 1,\n \"partParameter\": \"clkPin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n },\n \"pixels\": {\n \"simulationBehavior\": \"pixels\",\n \"visual\": { \n \"builtIn\": \"pixels\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"MOSI\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCK\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n }, \n \"buttons\": {\n \"simulationBehavior\": \"buttons\",\n \"visual\": {\n \"builtIn\": \"buttons\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 45\n }\n ]\n },\n \"numberOfPins\": 2,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"button\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"slideswitch\": {\n \"numberOfPins\": 3,\n \"simulationBehavior\": \"slideswitch\",\n \"visual\": {\n \"builtIn\": \"slideswitch\",\n \"width\": 100,\n \"height\": 100,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 0\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 5\n },\n {\n \"x\": 37,\n \"y\": 5\n },\n {\n \"x\": 45,\n \"y\": 5\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"led\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"analogled\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"photocell\": {\n \"numberOfPins\": 3,\n \"visual\": {\n \"builtIn\": \"photocell\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 15,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"photocell\",\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n }\n}", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace light {\n\n /**\n * Send a programmable light buffer to the specified digital pin\n * @param data The pin that the lights are connected to\n * @param clk the clock line if any\n * @param mode the color encoding mode\n * @param buf The buffer to send to the pin\n */\n //% shim=light::sendBuffer\n function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n /**\n * Determines if the USB has been enumerated.\n */\n //% shim=control::isUSBInitialized\n function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n /**\n * Get a pin by configuration id (DAL.CFG_PIN...)\n */\n //% shim=pins::pinByCfg\n function pinByCfg(key: int32): DigitalInOutPin;\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=pins::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration blockGap=8\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=19 shim=pins::pulseDuration\n function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read weight=53\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n //% blockNamespace=pins\n //% parts=\"photocell\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=AnalogInPinMethods::analogRead\n analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write weight=52\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n //% blockNamespace=pins\n //%parts=\"analogled\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.min=0 value.max=1023\n //% trackArgs=0 shim=AnalogOutPinMethods::analogWrite\n analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read weight=61\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalRead\n digitalRead(): boolean;\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin\n */\n //% help=pins/digital-write weight=60\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n //% parts=\"led\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalWrite\n digitalWrite(value: boolean): void;\n\n /**\n * Make this pin a digital input, and create events where the timestamp is the duration\n * that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=16 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n onPulsed(pulse: PulseValue, body: () => void): void;\n\n /**\n * Register code to run when a pin event occurs.\n */\n //% help=pins/on-event weight=20 blockGap=8\n //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::onEvent\n onEvent(event: PinEvent, body: () => void): void;\n\n /**\n * Return the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %high||timeout %maxDuration (µs)\"\n //% weight=18 blockGap=8\n //% help=\"pins/pulse-in\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n /**\n * Set the pull direction of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone\n */\n //% help=pins/set-pull weight=17 blockGap=8\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n /**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=51\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n analogSetPeriod(period: int32): void;\n\n /**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed\n */\n //% help=pins/servo-write weight=41 group=\"Servo\"\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n //% parts=microservo trackArgs=0\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n servoWrite(value?: int32): void;\n\n /**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n //% parts=microservo blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n servoSetPulse(duration: int32): void;\n\n /**\n * Indicates if the servo is running continuously\n */\n //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n /**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n //% help=control/raise-event\n //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n function raiseEvent(src: int32, value: int32): void;\n\n /**\n * Determine the version of system software currently running.\n */\n //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n //% help=control/device-dal-version shim=control::deviceDalVersion\n function deviceDalVersion(): string;\n\n /**\n * Allocates the next user notification event\n */\n //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n function allocateNotifyEvent(): int32;\n\n /** Write a message to DMESG debugging buffer. */\n //% shim=control::dmesg\n function dmesg(s: string): void;\n\n /** Write a message and value (pointer) to DMESG debugging buffer. */\n //% shim=control::dmesgPtr\n function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::readBuffer\n readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::writeBuffer\n writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n /**\n * Opens a Serial communication driver\n */\n //% help=pins/create-i2c\n //% parts=i2c shim=pins::createI2C\n function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n /**\n * Opens a SPI driver\n */\n //% help=pins/create-spi\n //% parts=spi shim=pins::createSPI\n function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n /**\n * Opens a slave SPI driver\n */\n //% parts=spi shim=pins::createSlaveSPI\n function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n /**\n * Write to the SPI bus\n */\n //% shim=SPIMethods::write\n write(value: int32): int32;\n\n /**\n * Transfer buffers over the SPI bus\n */\n //% argsNullable shim=SPIMethods::transfer\n transfer(command: Buffer, response: Buffer): void;\n\n /**\n * Sets the SPI clock frequency\n */\n //% shim=SPIMethods::setFrequency\n setFrequency(frequency: int32): void;\n\n /**\n * Sets the SPI bus mode\n */\n //% shim=SPIMethods::setMode\n setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n /**\n * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n * @param value the data (max 32 characters)\n */\n //% shim=configStorage::setBuffer\n function setBuffer(key: string, value: Buffer): void;\n\n /**\n * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::getBuffer\n function getBuffer(key: string): Buffer;\n\n /**\n * Removes the key from local storage\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::removeItem\n function removeItem(key: string): void;\n\n /**\n * Clears the local storage\n */\n //% shim=configStorage::clear\n function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -730,7 +731,7 @@ "platform.cpp": "#include \"pxt.h\"\n#include \"STM32LowLevelTimer.h\"\n#include \"Accelerometer.h\"\n\nnamespace pxt {\n\nstruct TimerConfig {\n uint8_t id;\n uint8_t irqn;\n TIM_TypeDef *addr;\n};\n\n#define DEF_TIM(n) \\\n { 0x10 + n, TIM##n##_IRQn, TIM##n }\n\nstatic const TimerConfig timers[] = {\n#ifdef TIM1\n DEF_TIM(1),\n#endif\n#ifdef TIM2\n DEF_TIM(2),\n#endif\n#ifdef TIM3\n DEF_TIM(3),\n#endif\n#ifdef TIM4\n DEF_TIM(4),\n#endif\n#ifdef TIM5\n DEF_TIM(5),\n#endif\n#ifdef TIM6\n DEF_TIM(6),\n#endif\n#ifdef TIM7\n DEF_TIM(7),\n#endif\n#ifdef TIM8\n DEF_TIM(8),\n#endif\n#ifdef TIM9\n DEF_TIM(9),\n#endif\n#ifdef TIM10\n DEF_TIM(10),\n#endif\n#ifdef TIM11\n DEF_TIM(11),\n#endif\n#ifdef TIM12\n DEF_TIM(12),\n#endif\n#ifdef TIM13\n DEF_TIM(13),\n#endif\n#ifdef TIM14\n DEF_TIM(14),\n#endif\n#ifdef TIM15\n DEF_TIM(15),\n#endif\n {0, 0, 0}};\n\n#ifdef STM32F1\n#define DEF_TIMERS 0x14120000 // TIM4 TIM2\n#else\n#define DEF_TIMERS 0x15120000 // TIM5 TIM2\n#endif\n\nstatic uint32_t usedTimers;\nstatic int timerIdx(uint8_t id) {\n for (unsigned i = 0; timers[i].id; i++) {\n if (id == timers[i].id)\n return i;\n }\n return -1;\n}\nLowLevelTimer *allocateTimer() {\n uint32_t timersToUse = getConfig(CFG_TIMERS_TO_USE, DEF_TIMERS);\n for (int shift = 24; shift >= 0; shift -= 8) {\n uint8_t tcId = (timersToUse >> shift) & 0xff;\n int idx = timerIdx(tcId);\n if (idx < 0 || (usedTimers & (1 << idx)))\n continue;\n auto dev = timers[idx].addr;\n if (dev->CR1 & TIM_CR1_CEN)\n continue;\n usedTimers |= 1 << idx;\n DMESG(\"allocate TIM%d\", tcId - 0x10);\n return new STM32LowLevelTimer(dev, (IRQn_Type)timers[idx].irqn);\n }\n\n target_panic(PANIC_OUT_OF_TIMERS);\n return NULL;\n}\n\nvoid initAccelRandom();\n#ifdef STM32F4\nextern \"C\" void apply_clock_init(RCC_OscInitTypeDef *oscInit, RCC_ClkInitTypeDef *clkConfig, uint32_t flashLatency) {\n\n int mhz = getConfig(CFG_CPU_MHZ, 84);\n\n if (mhz >= 216) {\n oscInit->PLL.PLLN = 432;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 9;\n flashLatency = FLASH_LATENCY_6;\n } else if (mhz >= 192) {\n oscInit->PLL.PLLN = 384;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 8;\n flashLatency = FLASH_LATENCY_6;\n } else if (mhz >= 168) {\n oscInit->PLL.PLLN = 336;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 7;\n flashLatency = FLASH_LATENCY_5;\n } else if (mhz >= 144) {\n oscInit->PLL.PLLN = 288;\n oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n oscInit->PLL.PLLQ = 6;\n flashLatency = FLASH_LATENCY_5;\n } else if (mhz >= 108) {\n oscInit->PLL.PLLN = 432;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 9;\n flashLatency = FLASH_LATENCY_4;\n } else if (mhz >= 96) {\n oscInit->PLL.PLLN = 384;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 8;\n flashLatency = FLASH_LATENCY_3;\n } else if (mhz >= 84) {\n // this is the default from codal\n oscInit->PLL.PLLN = 336;\n oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n oscInit->PLL.PLLQ = 7;\n flashLatency = FLASH_LATENCY_2;\n } else {\n target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n }\n\n DMESG(\"CPU clock: %dMHz -> %dMHz\", mhz, oscInit->PLL.PLLN / (oscInit->PLL.PLLP == RCC_PLLP_DIV4 ? 4 : 2));\n\n if (mhz > 108) {\n clkConfig->APB1CLKDivider = RCC_HCLK_DIV4;\n clkConfig->APB2CLKDivider = RCC_HCLK_DIV2;\n } else {\n clkConfig->APB1CLKDivider = RCC_HCLK_DIV2;\n clkConfig->APB2CLKDivider = RCC_HCLK_DIV1;\n }\n\n HAL_RCC_OscConfig(oscInit);\n HAL_RCC_ClockConfig(clkConfig, flashLatency);\n}\n#endif\n\n// Disable seeding random from accelerometer. We now store random\n// seed in internal flash, so it's different on every reset, and\n// accelerometer sometimes have bugs, so better not enable them unless\n// requested.\nstatic void initRandomSeed() {\n#if 0\n if (getConfig(CFG_ACCELEROMETER_TYPE, -1) != -1) {\n initAccelRandom();\n }\n#endif\n}\n\nstatic void set_if_present(int cfg, int val) {\n auto snd = pxt::lookupPinCfg(cfg);\n if (snd)\n snd->setDigitalValue(val);\n}\n\n//%\nvoid deepSleep() {\n // this in particular puts accelerometer to sleep, which the bootloader\n // doesn't do\n CodalComponent::setAllSleep(true);\n\n#ifdef STM32F4\n // ask bootloader to do the deep sleeping\n QUICK_BOOT(1);\n RTC->BKP1R = 0x10b37889;\n NVIC_SystemReset();\n#endif\n}\n\nvoid platformSendSerial(const char *data, int len) {\n /*\n if (!serial) {\n serial = new codal::_mbed::Serial(USBTX, NC);\n serial->baud(9600);\n }\n serial->send((uint8_t*)data, len);\n */\n}\n\nvoid platform_init() {\n initRandomSeed();\n setSendToUART(platformSendSerial);\n\n // make sure sound doesn't draw power before enabled\n set_if_present(CFG_PIN_JACK_SND, 0);\n set_if_present(CFG_PIN_JACK_HPEN, 0);\n set_if_present(CFG_PIN_JACK_BZEN, 1);\n\n /*\n if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n *HF2_DBG_MAGIC_PTR = 0;\n // this will cause alignment fault at the first breakpoint\n globals[0] = (TValue)1;\n }\n */\n}\n\nint *getBootloaderConfigData() {\n#ifdef STM32F4\n auto config_data = (uint32_t)(UF2_BINFO->configValues);\n if (config_data && (config_data & 3) == 0) {\n auto p = (uint32_t *)config_data - 4;\n if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1)\n return (int *)p + 4;\n }\n#endif\n\n return NULL;\n}\n\n#define STM32_UUID ((uint32_t *)0x1FFF7A10)\n\n#if CONFIG_ENABLED(DEVICE_USB)\nstatic void writeHex(char *buf, uint32_t n) {\n int i = 0;\n int sh = 28;\n while (sh >= 0) {\n int d = (n >> sh) & 0xf;\n buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d;\n sh -= 4;\n }\n buf[i] = 0;\n}\n#endif\n\nvoid platform_usb_init() {\n#if CONFIG_ENABLED(DEVICE_USB)\n static char serial_number[25];\n\n writeHex(serial_number, STM32_UUID[0]);\n writeHex(serial_number + 8, STM32_UUID[1]);\n writeHex(serial_number + 16, STM32_UUID[2]);\n\n usb.stringDescriptors[2] = serial_number;\n#endif\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {}\n", "platform.h": "#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"MultiButton.h\"\n#include \"STM32I2C.h\"\n#include \"STM32Pin.h\"\n#include \"STM32SPI.h\"\n#include \"STM32Serial.h\"\n#include \"Timer.h\"\n\n#include \"pinmap.h\"\n\n#define BOOTLOADER_START 0x08000000\n#define BOOTLOADER_END 0x08008000\n\n#ifdef STM32F4\n#define SETTINGS_MAGIC_0 0x10476643\n#define SETTINGS_MAGIC_1 0x2e9a5026\n\nstruct F4_Settings {\n uint32_t magic0;\n uint32_t magic1;\n int *configValues;\n uint32_t hseValue;\n const char *info_uf2;\n const char *manufacturer;\n const char *device;\n uint32_t reserved[16 - 7];\n};\n\n#define UF2_BINFO ((F4_Settings *)(BOOTLOADER_END - sizeof(F4_Settings)))\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#define USB_HANDOVER 0\n\n#define BOOT_RTC_SIGNATURE 0x71a21877\n#define APP_RTC_SIGNATURE 0x24a22d12\n#define HF2_RTC_SIGNATURE 0x39a63a78\n#define QUICK_BOOT(v) \\\n do { \\\n RTC->BKP0R = v ? APP_RTC_SIGNATURE : HF2_RTC_SIGNATURE; \\\n } while (0)\n#else\n#define QUICK_BOOT(v) ((void)0)\n#endif\n\n#define PAGE_SIZE 1024 // not really\n\n#define DEV_NUM_PINS 64\n\n#ifdef STM32F1\n#define DEV_PWM_PINS 0b111100000011101100001110111000111111001110LL\n#else\n#define DEV_PWM_PINS 0b111100000011100111111110111000111111101111LL\n#endif\n\n// CCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAA\n// fedcba9876543210fedcba9876543210fedcba9876543210\n#define DEV_AIN_PINS 0b000011111100000000000000110000000011111111LL\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_SERIAL codal::STM32Serial\n#define CODAL_PIN codal::STM32Pin\n#define CODAL_TIMER Timer\n#define CODAL_SPI codal::STM32SPI\n#define CODAL_I2C codal::STM32I2C\n#define CODAL_JACDAC_WIRE_SERIAL codal::ZSingleWireSerial\n\n#define PERF_NOW() (TIM5->CNT)\n\n#define IMAGE_BITS 4\n\n#define ALT0 0x000\n#define ALT1 0x100\n#define ALT2 0x200\n\n// The parameters below needs tuning!\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n\n#define PA_0 0x00\n#define PA_0_ALT0 PA_0 | ALT0\n#define PA_1 0x01\n#define PA_1_ALT0 PA_1 | ALT0\n#define PA_2 0x02\n#define PA_2_ALT0 PA_2 | ALT0\n#define PA_3 0x03\n#define PA_3_ALT0 PA_3 | ALT0\n#define PA_4 0x04\n#define PA_4_ALT0 PA_4 | ALT0\n#define PA_5 0x05\n#define PA_5_ALT0 PA_5 | ALT0\n#define PA_6 0x06\n#define PA_6_ALT0 PA_6 | ALT0\n#define PA_7 0x07\n#define PA_7_ALT0 PA_7 | ALT0\n#define PA_7_ALT1 PA_7 | ALT1\n#define PA_7_ALT2 PA_7 | ALT2\n#define PA_8 0x08\n#define PA_9 0x09\n#define PA_10 0x0A\n#define PA_11 0x0B\n#define PA_12 0x0C\n#define PA_13 0x0D\n#define PA_14 0x0E\n#define PA_15 0x0F\n#define PA_15_ALT0 PA_15 | ALT0\n#define PB_0 0x10\n#define PB_0_ALT0 PB_0 | ALT0\n#define PB_0_ALT1 PB_0 | ALT1\n#define PB_1 0x11\n#define PB_1_ALT0 PB_1 | ALT0\n#define PB_1_ALT1 PB_1 | ALT1\n#define PB_2 0x12\n#define PB_3 0x13\n#define PB_3_ALT0 PB_3 | ALT0\n#define PB_4 0x14\n#define PB_4_ALT0 PB_4 | ALT0\n#define PB_5 0x15\n#define PB_5_ALT0 PB_5 | ALT0\n#define PB_6 0x16\n#define PB_6_ALT0 PB_6 | ALT0\n#define PB_7 0x17\n#define PB_7_ALT0 PB_7 | ALT0\n#define PB_8 0x18\n#define PB_8_ALT0 PB_8 | ALT0\n#define PB_9 0x19\n#define PB_9_ALT0 PB_9 | ALT0\n#define PB_10 0x1A\n#define PB_11 0x1B\n#define PB_12 0x1C\n#define PB_13 0x1D\n#define PB_13_ALT0 PB_13 | ALT0\n#define PB_14 0x1E\n#define PB_14_ALT0 PB_14 | ALT0\n#define PB_14_ALT1 PB_14 | ALT1\n#define PB_15 0x1F\n#define PB_15_ALT0 PB_15 | ALT0\n#define PB_15_ALT1 PB_15 | ALT1\n#define PC_0 0x20\n#define PC_0_ALT0 PC_0 | ALT0\n#define PC_0_ALT1 PC_0 | ALT1\n#define PC_1 0x21\n#define PC_1_ALT0 PC_1 | ALT0\n#define PC_1_ALT1 PC_1 | ALT1\n#define PC_2 0x22\n#define PC_2_ALT0 PC_2 | ALT0\n#define PC_2_ALT1 PC_2 | ALT1\n#define PC_3 0x23\n#define PC_3_ALT0 PC_3 | ALT0\n#define PC_3_ALT1 PC_3 | ALT1\n#define PC_4 0x24\n#define PC_4_ALT0 PC_4 | ALT0\n#define PC_5 0x25\n#define PC_5_ALT0 PC_5 | ALT0\n#define PC_6 0x26\n#define PC_6_ALT0 PC_6 | ALT0\n#define PC_7 0x27\n#define PC_7_ALT0 PC_7 | ALT0\n#define PC_8 0x28\n#define PC_8_ALT0 PC_8 | ALT0\n#define PC_9 0x29\n#define PC_9_ALT0 PC_9 | ALT0\n#define PC_10 0x2A\n#define PC_10_ALT0 PC_10 | ALT0\n#define PC_11 0x2B\n#define PC_11_ALT0 PC_11 | ALT0\n#define PC_12 0x2C\n#define PC_13 0x2D\n#define PC_14 0x2E\n#define PC_15 0x2F\n#define PD_0 0x30\n#define PD_1 0x31\n#define PD_2 0x32\n#define PD_3 0x33\n#define PD_4 0x34\n#define PD_5 0x35\n#define PD_6 0x36\n#define PD_7 0x37\n#define PD_8 0x38\n#define PD_9 0x39\n#define PD_10 0x3A\n#define PD_11 0x3B\n#define PD_12 0x3C\n#define PD_13 0x3D\n#define PD_14 0x3E\n#define PD_15 0x3F\n#define PE_0 0x40\n#define PE_1 0x41\n#define PE_2 0x42\n#define PE_3 0x43\n#define PE_4 0x44\n#define PE_5 0x45\n#define PE_6 0x46\n#define PE_7 0x47\n#define PE_8 0x48\n#define PE_9 0x49\n#define PE_10 0x4A\n#define PE_11 0x4B\n#define PE_12 0x4C\n#define PE_13 0x4D\n#define PE_14 0x4E\n#define PE_15 0x4F\n\n#endif\n\n#endif\n", "pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n", - "pxt.json": "{\n \"name\": \"core---stm32\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", + "pxt.json": "{\n \"name\": \"core---stm32\",\n \"description\": \"The core library for Codal-based targets\",\n \"dependencies\": {\n \"base\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"dal.d.ts\",\n \"codal.cpp\",\n \"usb.cpp\",\n \"pxt.h\",\n \"platform.h\",\n \"platform.cpp\",\n \"pxtcore.h\",\n \"pins.h\",\n \"pins.cpp\",\n \"pinsAnalog.cpp\",\n \"pinsDigital.cpp\",\n \"pinsPWM.cpp\",\n \"pins.ts\",\n \"pinscompat.ts\",\n \"control.cpp\",\n \"i2c.cpp\",\n \"i2c.ts\",\n \"spi.cpp\",\n \"spi.ts\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"hf2.cpp\",\n \"hf2.h\",\n \"hf2dbg.h\",\n \"uf2format.h\",\n \"uf2hid.h\",\n \"ns.ts\",\n \"dmac.cpp\",\n \"dmac.h\",\n \"timer.ts\",\n \"light.cpp\",\n \"light.h\",\n \"keyvaluestorage.cpp\",\n \"keyvaluestorage.ts\",\n \"leveldetector.ts\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"yotta\": {\n \"config\": {\n \"codal\": {\n \"component_count\": 64,\n \"dmesg_buffer_size\": 1024\n }\n }\n },\n \"dalDTS\": {\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"JD_\",\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\",\n \"MAG_\",\n \"MAG3\",\n \"MPU6\",\n \"MADCTL\",\n \"MMA8\"\n ]\n }\n}\n", "pxtcore.h": "#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n", "pxtparts.json": "{\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 19,\n \"y\": 0\n },\n {\n \"x\": 28,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"dotstar\": {\n \"simulationBehavior\": \"dotstar\",\n \"visual\": {\n \"builtIn\": \"dotstar\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 1\n },\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"light.createAPA102Strip\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"dataPin\"\n },\n {\n \"pinInstantiationIdx\": 1,\n \"partParameter\": \"clkPin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n },\n \"pixels\": {\n \"simulationBehavior\": \"pixels\",\n \"visual\": { \n \"builtIn\": \"pixels\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 17,\n \"y\": 0\n },\n {\n \"x\": 24,\n \"y\": 0\n },\n {\n \"x\": 31,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"MOSI\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCK\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"solder\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1, 2\n ]\n },\n {\n \"pinIndices\": [\n 3\n ]\n }\n ]\n }, \n \"buttons\": {\n \"simulationBehavior\": \"buttons\",\n \"visual\": {\n \"builtIn\": \"buttons\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 45\n }\n ]\n },\n \"numberOfPins\": 2,\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"button\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"slideswitch\": {\n \"numberOfPins\": 3,\n \"simulationBehavior\": \"slideswitch\",\n \"visual\": {\n \"builtIn\": \"slideswitch\",\n \"width\": 100,\n \"height\": 100,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 0\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 5\n },\n {\n \"x\": 37,\n \"y\": 5\n },\n {\n \"x\": 45,\n \"y\": 5\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"led\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"analogled\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"builtIn\": \"led\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"led\",\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"photocell\": {\n \"numberOfPins\": 3,\n \"visual\": {\n \"builtIn\": \"photocell\",\n \"width\": 68,\n \"height\": 180,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 15,\n \"y\": 0\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"photocell\",\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n }\n}", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace light {\n\n /**\n * Send a programmable light buffer to the specified digital pin\n * @param data The pin that the lights are connected to\n * @param clk the clock line if any\n * @param mode the color encoding mode\n * @param buf The buffer to send to the pin\n */\n //% shim=light::sendBuffer\n function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n /**\n * Determines if the USB has been enumerated.\n */\n //% shim=control::isUSBInitialized\n function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n /**\n * Get a pin by configuration id (DAL.CFG_PIN...)\n */\n //% shim=pins::pinByCfg\n function pinByCfg(key: int32): DigitalInOutPin;\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=pins::createBuffer\n function createBuffer(size: int32): Buffer;\n\n /**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration blockGap=8\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=19 shim=pins::pulseDuration\n function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read weight=53\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n //% blockNamespace=pins\n //% parts=\"photocell\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=AnalogInPinMethods::analogRead\n analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write weight=52\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n //% blockNamespace=pins\n //%parts=\"analogled\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.min=0 value.max=1023\n //% trackArgs=0 shim=AnalogOutPinMethods::analogWrite\n analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read weight=61\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalRead\n digitalRead(): boolean;\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin\n */\n //% help=pins/digital-write weight=60\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n //% parts=\"led\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::digitalWrite\n digitalWrite(value: boolean): void;\n\n /**\n * Make this pin a digital input, and create events where the timestamp is the duration\n * that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=16 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n onPulsed(pulse: PulseValue, body: () => void): void;\n\n /**\n * Register code to run when a pin event occurs.\n */\n //% help=pins/on-event weight=20 blockGap=8\n //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n //% blockNamespace=pins\n //% parts=\"slideswitch\"\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4\n //% trackArgs=0 shim=DigitalInOutPinMethods::onEvent\n onEvent(event: PinEvent, body: () => void): void;\n\n /**\n * Return the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %high||timeout %maxDuration (µs)\"\n //% weight=18 blockGap=8\n //% help=\"pins/pulse-in\"\n //% blockNamespace=pins\n //% pin.fieldEditor=\"gridpicker\"\n //% pin.fieldOptions.width=220\n //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n /**\n * Set the pull direction of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone\n */\n //% help=pins/set-pull weight=17 blockGap=8\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n /**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=51\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n analogSetPeriod(period: int32): void;\n\n /**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed\n */\n //% help=pins/servo-write weight=41 group=\"Servo\"\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n //% parts=microservo trackArgs=0\n //% blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4\n //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n servoWrite(value?: int32): void;\n\n /**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n //% parts=microservo blockNamespace=pins\n //% name.fieldEditor=\"gridpicker\"\n //% name.fieldOptions.width=220\n //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n servoSetPulse(duration: int32): void;\n\n /**\n * Indicates if the servo is running continuously\n */\n //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n /**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n //% help=control/raise-event\n //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n function raiseEvent(src: int32, value: int32): void;\n\n /**\n * Determine the version of system software currently running.\n */\n //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n //% help=control/device-dal-version shim=control::deviceDalVersion\n function deviceDalVersion(): string;\n\n /**\n * Allocates the next user notification event\n */\n //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n function allocateNotifyEvent(): int32;\n\n /** Write a message to DMESG debugging buffer. */\n //% shim=control::dmesg\n function dmesg(s: string): void;\n\n /** Write a message and value (pointer) to DMESG debugging buffer. */\n //% shim=control::dmesgPtr\n function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::readBuffer\n readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=I2CMethods::writeBuffer\n writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n /**\n * Opens a Serial communication driver\n */\n //% help=pins/create-i2c\n //% parts=i2c shim=pins::createI2C\n function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n /**\n * Opens a SPI driver\n */\n //% help=pins/create-spi\n //% parts=spi shim=pins::createSPI\n function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n /**\n * Opens a slave SPI driver\n */\n //% parts=spi shim=pins::createSlaveSPI\n function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n /**\n * Write to the SPI bus\n */\n //% shim=SPIMethods::write\n write(value: int32): int32;\n\n /**\n * Transfer buffers over the SPI bus\n */\n //% argsNullable shim=SPIMethods::transfer\n transfer(command: Buffer, response: Buffer): void;\n\n /**\n * Sets the SPI clock frequency\n */\n //% shim=SPIMethods::setFrequency\n setFrequency(frequency: int32): void;\n\n /**\n * Sets the SPI bus mode\n */\n //% shim=SPIMethods::setMode\n setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n /**\n * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n * @param value the data (max 32 characters)\n */\n //% shim=configStorage::setBuffer\n function setBuffer(key: string, value: Buffer): void;\n\n /**\n * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::getBuffer\n function getBuffer(key: string): Buffer;\n\n /**\n * Removes the key from local storage\n * @param key the identifier (max 16 characters)\n */\n //% shim=configStorage::removeItem\n function removeItem(key: string): void;\n\n /**\n * Clears the local storage\n */\n //% shim=configStorage::clear\n function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -749,13 +750,13 @@ "config.ts": "namespace config {\n \n // ====================================================\n // === UART =======================================\n // ================================================\n export const PIN_UART1_TX = DAL.PB_6;\n export const PIN_UART1_RX = DAL.PB_7;\n \n export const PIN_UART2_TX = DAL.PD_5;\n export const PIN_UART2_RX = DAL.PD_6;\n \n export const PIN_UART3_TX = DAL.PD_8;\n export const PIN_UART3_RX = DAL.PD_9;\n \n export const PIN_UART4_TX = DAL.PA_0;\n export const PIN_UART4_RX = DAL.PA_1;\n \n\n // ====================================================\n // === SPI ========================================\n // ================================================\n export const PIN_SPI1_MISO = DAL.PA_6;\n export const PIN_SPI1_MOSI = DAL.PA_7_ALT1;\n export const PIN_SPI1_SCK = DAL.PA_5;\n \n export const PIN_SPI2_MISO = DAL.PD_3;\n export const PIN_SPI2_MOSI = DAL.PD_4;\n export const PIN_SPI2_SCK = DAL.PD_1;\n \n export const PIN_SPI3_MISO = DAL.PC_11;\n export const PIN_SPI3_MOSI = DAL.PC_12;\n export const PIN_SPI3_SCK = DAL.PC_10;\n\n\n // ====================================================\n // === I2C ========================================\n // ================================================\n export const PIN_I2C1_SCL = DAL.PB_8;\n export const PIN_I2C1_SDA = DAL.PB_9;\n \n export const PIN_I2C2_SCL = DAL.PB_10;\n export const PIN_I2C2_SDA = DAL.PB_11;\n\n \n // ====================================================\n // === PERIPHERALS ================================\n // ================================================\n export const PIN_ACCELEROMETER_SDA = PIN_I2C2_SDA;\n export const PIN_ACCELEROMETER_SCL = PIN_I2C2_SCL;\n export const PIN_ACCELEROMETER_INT = DAL.PD_11; \n\n export const PIN_HTS221_SDA = PIN_I2C2_SDA;\n export const PIN_HTS221_SCL = PIN_I2C2_SCL;\n\n export const PIN_LPS22HB_SDA = PIN_I2C2_SDA;\n export const PIN_LPS22HB_SCL = PIN_I2C2_SCL;\n\n export const PIN_VL53L0X_SDA = PIN_I2C2_SDA;\n export const PIN_VL53L0X_SCL = PIN_I2C2_SCL;\n export const PIN_VL53L0X_SHUT = DAL.PC_6;\n\n export const PIN_LSM6DSL_SDA = PIN_I2C2_SDA;\n export const PIN_LSM6DSL_SCL = PIN_I2C2_SCL;\n\n export const PIN_BLE_SPI_MOSI = PIN_SPI3_MOSI;\n export const PIN_BLE_SPI_MISO = PIN_SPI3_MISO;\n export const PIN_BLE_SPI_SCLK = PIN_SPI3_SCK;\n\n export const PIN_BLE_SPI_CS = DAL.PD_13;\n export const PIN_BLE_SPI_IRQ = DAL.PE_6;\n export const PIN_BLE_RST = DAL.PA_8;\n\n export const PIN_WIFI_ISM43362_MOSI = PIN_SPI3_MOSI;\n export const PIN_WIFI_ISM43362_MISO = PIN_SPI3_MISO;\n export const PIN_WIFI_ISM43362_SCK = PIN_SPI3_SCK;\n \n export const PIN_WIFI_ISM43362_CS = DAL.PE_0;\n export const PIN_WIFI_ISM43362_COMMAND_DATA_READY = DAL.PE_1;\n export const PIN_WIFI_ISM43362_RESET = DAL.PE_8;\n export const PIN_WIFI_ISM43362_WAKE_UP = DAL.PB_13;\n \n\n // ====================================================\n // === ARDUINO ====================================\n // ================================================\n export const PIN_A0 = DAL.PC_5;\n export const PIN_A1 = DAL.PC_4;\n export const PIN_A2 = DAL.PC_3;\n export const PIN_A3 = DAL.PC_2;\n export const PIN_A4 = DAL.PC_1;\n export const PIN_A5 = DAL.PC_0;\n\n export const PIN_D0 = DAL.PA_1;\n export const PIN_D1 = DAL.PA_0;\n export const PIN_D2 = DAL.PD_14;\n export const PIN_D3 = DAL.PB_0_ALT1;\n export const PIN_D4 = DAL.PA_3;\n export const PIN_D5 = DAL.PB_4;\n export const PIN_D6 = DAL.PB_1_ALT1;\n export const PIN_D7 = DAL.PA_4;\n export const PIN_D8 = DAL.PB_2;\n export const PIN_D9 = DAL.PA_15;\n export const PIN_D10 = DAL.PA_2;\n export const PIN_D11 = DAL.PA_7_ALT1;\n export const PIN_D12 = DAL.PA_6;\n export const PIN_D13 = DAL.PA_5;\n export const PIN_D14 = DAL.PB_9;\n export const PIN_D15 = DAL.PB_8;\n\n export const PIN_RX = PIN_UART1_RX;\n export const PIN_TX = PIN_UART1_TX;\n\n export const PIN_MISO = PIN_SPI1_MISO;\n export const PIN_MOSI = PIN_SPI1_MOSI;\n export const PIN_SCK = PIN_SPI1_SCK;\n\n export const PIN_SCL = PIN_I2C1_SCL;\n export const PIN_SDA = PIN_I2C1_SDA;\n\n\n // ====================================================\n // === ON-BOARD COMPONENTS ========================\n // ================================================\n export const PIN_LED = DAL.PA_5;\n export const PIN_LED2 = DAL.PB_14;\n export const PIN_LED3 = DAL.PC_9;\n\n export const PIN_BTN_USER = DAL.PC_13;\n export const PIN_RESET = DAL.NO_CONN;\n export const PIN_TEMPERATURE = DAL.NO_CONN;\n\n\n // ====================================================\n // === EXTERNAL DEFINITION ========================\n // ================================================\n export const PIN_SPEAKER_AMP = PIN_D3;\n}\n", "device.d.ts": "declare namespace pins {\n //% fixedInstance shim=pxt::getPin(PIN_A0)\n const A0: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A1)\n const A1: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A2)\n const A2: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A3)\n const A3: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A4)\n const A4: AnalogInPin;\n //% fixedInstance shim=pxt::getPin(PIN_A5)\n const A5: AnalogInPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_D0)\n const D0: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D1)\n const D1: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D2)\n const D2: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D3)\n const D3: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D4)\n const D4: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D5)\n const D5: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D6)\n const D6: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D7)\n const D7: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_D8)\n const D8: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D9)\n const D9: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D10)\n const D10: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D11)\n const D11: PwmPin;\n //% fixedInstance shim=pxt::getPin(PIN_D12)\n const D12: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D13)\n const D13: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D14)\n const D14: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_D15)\n const D15: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_LED)\n const LED: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_LED2)\n const LED2: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_LED3)\n const LED3: DigitalInOutPin;\n\n //% fixedInstance shim=pxt::getPin(PIN_RX)\n const RX: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_TX)\n const TX: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_MISO)\n const MISO: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_MOSI)\n const MOSI: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SCK)\n const SCK: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SCL)\n const SCL: DigitalInOutPin;\n //% fixedInstance shim=pxt::getPin(PIN_SDA)\n const SDA: DigitalInOutPin;\n}\n\ndeclare namespace input {\n /**\n * Button connecting A0 to GND.\n */\n //% block=\"button A0\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A0,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA0: Button;\n\n /**\n * Button connecting A1 to GND.\n */\n //% block=\"button A1\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A1,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA1: Button;\n\n /**\n * Button connecting A2 to GND.\n */\n //% block=\"button A2\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A2,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA2: Button;\n\n /**\n * Button connecting A3 to GND.\n */\n //% block=\"button A3\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A3,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA3: Button;\n\n /**\n * Button connecting A4 to GND.\n */\n //% block=\"button A4\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A4,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA4: Button;\n\n /**\n * Button connecting A5 to GND.\n */\n //% block=\"button A5\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_A5,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonA5: Button;\n\n /**\n * Button connecting D0 to GND.\n */\n //% block=\"button D0\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D0,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD0: Button;\n\n /**\n * Button connecting D1 to GND.\n */\n //% block=\"button D1\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D1,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD1: Button;\n\n /**\n * Button connecting D2 to GND.\n */\n //% block=\"button D2\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D2,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD2: Button;\n\n /**\n * Button connecting D3 to GND.\n */\n //% block=\"button D3\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D3,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD3: Button;\n\n /**\n * Button connecting D4 to GND.\n */\n //% block=\"button D4\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D4,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD4: Button;\n\n /**\n * Button connecting D5 to GND.\n */\n //% block=\"button D5\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D5,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD5: Button;\n\n /**\n * Button connecting D6 to GND.\n */\n //% block=\"button D6\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D6,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD6: Button;\n\n /**\n * Button connecting D7 to GND.\n */\n //% block=\"button D7\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D7,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD7: Button;\n\n /**\n * Button connecting D8 to GND.\n */\n //% block=\"button D8\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D8,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD8: Button;\n\n /**\n * Button connecting D9 to GND.\n */\n //% block=\"button D9\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D9,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD9: Button;\n\n /**\n * Button connecting D10 to GND.\n */\n //% block=\"button D10\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D10,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD10: Button;\n\n /**\n * Button connecting D11 to GND.\n */\n //% block=\"button D11\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D11,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD11: Button;\n\n /**\n * Button connecting D12 to GND.\n */\n //% block=\"button D12\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D12,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD12: Button;\n\n /**\n * Button connecting D13 to GND.\n */\n //% block=\"button D13\" fixedInstance\n //% shim=pxt::getButtonByPin(PIN_D13,BUTTON_ACTIVE_LOW_PULL_UP)\n const buttonD13: Button;\n\n /**\n * Button connecting BTN_USER to GND.\n */\n //% block=\"button USER\" fixedInstance\n //% shim=pxt::getButton(0)\n const buttonUser: Button;\n}\n", "ns.ts": "//% color=\"#d65cd6\" weight=90\n//% groups='[\"Buttons\", \"Temperature\", \"Humidity\", \"Pressure\", \"Distance\", \"Movement\"]'\nnamespace input {\n}\n\n//% color=\"#EF2D56\" weight=80 advanced=false\nnamespace pins {\n}\n\n//% color=\"#00b295\" weight=70 advanced=true\nnamespace control {\n\n}\n\n//% color=\"#61b22f\" weight=70 \nnamespace loops {\n\n}\n\n//% color=\"#006E90\" weight=30 icon=\"\\uf1e6\" advanced=false\nnamespace serial {\n\n}", - "pxt.json": "{\n \"name\": \"stm32-discovery-DISCO_L475VG_IOT\",\n \"description\": \"DISCO_L475VG_IOT - beta\",\n \"dependencies\": {\n \"accelerometer---lsm6dsl\": \"*\",\n \"barometer---lps22hb\": \"*\",\n \"buttons\": \"*\",\n \"core---stm32\": \"*\",\n \"distance---vl53l0x\": \"*\",\n \"hygrometer---hts221\": \"*\",\n \"thermometer---lps22hb\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"ns.ts\",\n \"config.ts\",\n \"device.d.ts\",\n \"board.json\",\n \"board.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n },\n \"compileServiceVariant\": \"stm32-DISCO_L475VG_IOT\",\n \"core\": true,\n \"dalDTS\": {\n \"corePackage\": \"../core---stm32\"\n },\n \"features\": [\n \"pina0\",\n \"pina1\"\n ],\n \"icon\": \"/docs/static/libs/stm32-discovery-DISCO_L475VG_IOT.jpg\"\n}\n" + "pxt.json": "{\n \"name\": \"stm32-discovery-DISCO_L475VG_IOT\",\n \"description\": \"DISCO_L475VG_IOT - beta\",\n \"dependencies\": {\n \"accelerometer---lsm6dsl\": \"*\",\n \"barometer---lps22hb\": \"*\",\n \"buttons\": \"*\",\n \"core---stm32\": \"*\",\n \"distance---vl53l0x\": \"*\",\n \"hygrometer---hts221\": \"*\",\n \"thermometer---lps22hb\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"ns.ts\",\n \"config.ts\",\n \"device.d.ts\",\n \"board.json\",\n \"board.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n },\n \"compileServiceVariant\": \"stm32-DISCO_L475VG_IOT\",\n \"core\": true,\n \"dalDTS\": {\n \"corePackage\": \"../core---stm32\"\n },\n \"features\": [\n \"pina0\",\n \"pina1\"\n ],\n \"icon\": \"/docs/static/libs/stm32-discovery-DISCO_L475VG_IOT.jpg\"\n}\n" }, "buttons": { "README.md": "# buttons\n\nA library to handle 2 buttons A and B.\n", "buttons.cpp": "#include \"pxt.h\"\n\n/*\nThese button events need CODAL work.\n // % block=\"double click\"\n DoubleClick = DEVICE_BUTTON_EVT_DOUBLE_CLICK,\n // % block=\"hold\"\n Hold = DEVICE_BUTTON_EVT_HOLD\n*/\n\n/**\n * User interaction on buttons\n */\nenum class ButtonEvent {\n //% block=\"click\"\n Click = DEVICE_BUTTON_EVT_CLICK,\n //% block=\"long click\"\n LongClick = DEVICE_BUTTON_EVT_LONG_CLICK,\n //% block=\"up\"\n Up = DEVICE_BUTTON_EVT_UP,\n //% block=\"down\"\n Down = DEVICE_BUTTON_EVT_DOWN\n};\n\nnamespace pxt {\n//%\nButton *getButtonByPin(int pin, int flags) {\n auto cpid = DEVICE_ID_FIRST_BUTTON + pin;\n auto btn = (Button *)lookupComponent(cpid);\n if (btn == NULL) {\n auto pull = PullMode::None;\n if ((flags & 0xf0) == 0x10)\n pull = PullMode::Down;\n else if ((flags & 0xf0) == 0x20)\n pull = PullMode::Up;\n else if ((flags & 0xf0) == 0x20)\n pull = PullMode::None;\n else\n target_panic(42);\n btn = new Button(*lookupPin(pin), cpid, DEVICE_BUTTON_ALL_EVENTS, (ButtonPolarity)(flags & 0xf), pull);\n }\n return btn;\n}\n\n//%\nButton *getButtonByPinCfg(int key, int flags) {\n int pin = getConfig(key);\n if (pin == -1)\n target_panic(42);\n return getButtonByPin(pin, flags);\n}\n\nMultiButton *getMultiButton(int id, int pinA, int pinB, int flags) {\n auto btn = (MultiButton *)lookupComponent(id);\n if (btn == NULL) {\n auto bA = getButtonByPin(pinA, flags);\n auto bB = getButtonByPin(pinB, flags);\n btn = new codal::MultiButton(bA->id, bB->id, id);\n\n // A user has registered to receive events from the buttonAB multibutton.\n // Disable click events from being generated by ButtonA and ButtonB, and defer the\n // control of this to the multibutton handler.\n //\n // This way, buttons look independent unless a buttonAB is requested, at which\n // point button A+B clicks can be correclty handled without breaking\n // causal ordering.\n bA->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n bB->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n btn->setEventConfiguration(DEVICE_BUTTON_ALL_EVENTS);\n }\n return btn;\n}\n\n// This is for A, B, and AB\n//%\nAbstractButton *getButton(int id) {\n // int pa = getConfig(CFG_PIN_BTN_A);\n // int pb = getConfig(CFG_PIN_BTN_B);\n // int flags = getConfig(CFG_DEFAULT_BUTTON_MODE, BUTTON_ACTIVE_LOW_PULL_UP);\n // if (id == 0)\n // return getButtonByPin(pa, flags);\n // else if (id == 1)\n // return getButtonByPin(pb, flags);\n // else if (id == 2)\n // return getMultiButton(DEVICE_ID_BUTTON_AB, pa, pb, flags);\n // else {\n // target_panic(42);\n // return NULL;\n // }\n\n int pUser = getConfig(CFG_PIN_BTN_USER);\n int flags = getConfig(CFG_DEFAULT_BUTTON_MODE, BUTTON_ACTIVE_LOW_PULL_UP);\n\n if (id == 0) {\n return getButtonByPin(pUser, flags);\n } else {\n target_panic(42);\n return NULL;\n }\n}\n\n} // namespace pxt\n\nnamespace DigitalInOutPinMethods {\n\n/**\n * Get the push button (connected to GND) for given pin\n */\n//%\nButton_ pushButton(DigitalInOutPin pin) {\n return pxt::getButtonByPin((uint8_t)pin->name, BUTTON_ACTIVE_LOW_PULL_UP);\n}\n\n} // namespace DigitalInOutPinMethods\n\n//% noRefCounting fixedInstances\nnamespace ButtonMethods {\n\n/**\n * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n * @param button the button that needs to be clicked or used\n * @param event the kind of button gesture that needs to be detected\n * @param body code to run when the event is raised\n */\n//% help=input/button/on-event\n//% blockId=buttonEvent block=\"on %button|%event\"\n//% parts=\"buttons\"\n//% group=\"Buttons\"\n//% blockNamespace=input\n//% weight=96 blockGap=12\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% trackArgs=0\nvoid onEvent(Button_ button, ButtonEvent ev, Action body) {\n registerWithDal(button->id, (int)ev, body);\n}\n\n/**\n * Check if a button is pressed or not.\n * @param button the button to query the request\n */\n//% help=input/button/is-pressed\n//% block=\"%button|is pressed\"\n//% blockId=buttonIsPressed\n//% parts=\"buttons\"\n//% group=\"Buttons\"\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=50 blockGap=8\n//% trackArgs=0\nbool isPressed(Button_ button) {\n return button->isPressed();\n}\n\n/**\n * See if the button was pressed again since the last time you checked.\n * @param button the button to query the request\n */\n//% help=input/button/was-pressed\n//% block=\"%button|was pressed\"\n//% blockId=buttonWasPressed\n//% parts=\"buttons\"\n//% group=\"Buttons\" advanced=true\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=46 blockGap=8\n//% trackArgs=0\nbool wasPressed(Button_ button) {\n return button->wasPressed();\n}\n\n/**\n * Gets the component identifier for the buton\n */\n//%\nint id(Button_ button) {\n return button->id;\n}\n\n} // namespace ButtonMethods", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * User interaction on buttons\n */\n\n declare const enum ButtonEvent {\n //% block=\"click\"\n Click = 3, // DEVICE_BUTTON_EVT_CLICK\n //% block=\"long click\"\n LongClick = 4, // DEVICE_BUTTON_EVT_LONG_CLICK\n //% block=\"up\"\n Up = 2, // DEVICE_BUTTON_EVT_UP\n //% block=\"down\"\n Down = 1, // DEVICE_BUTTON_EVT_DOWN\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"buttons\",\n \"description\": \"Button A and B drivers\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"buttons.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"buttons\",\n \"description\": \"Button A and B drivers\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"buttons.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\ndeclare interface DigitalInOutPin {\n /**\n * Get the push button (connected to GND) for given pin\n */\n //% shim=DigitalInOutPinMethods::pushButton\n pushButton(): Button;\n}\n\n\n\n //% noRefCounting fixedInstances\ndeclare interface Button {\n /**\n * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n * @param button the button that needs to be clicked or used\n * @param event the kind of button gesture that needs to be detected\n * @param body code to run when the event is raised\n */\n //% help=input/button/on-event\n //% blockId=buttonEvent block=\"on %button|%event\"\n //% parts=\"buttons\"\n //% group=\"Buttons\"\n //% blockNamespace=input\n //% weight=96 blockGap=12\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% trackArgs=0 shim=ButtonMethods::onEvent\n onEvent(ev: ButtonEvent, body: () => void): void;\n\n /**\n * Check if a button is pressed or not.\n * @param button the button to query the request\n */\n //% help=input/button/is-pressed\n //% block=\"%button|is pressed\"\n //% blockId=buttonIsPressed\n //% parts=\"buttons\"\n //% group=\"Buttons\"\n //% blockNamespace=input\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% weight=50 blockGap=8\n //% trackArgs=0 shim=ButtonMethods::isPressed\n isPressed(): boolean;\n\n /**\n * See if the button was pressed again since the last time you checked.\n * @param button the button to query the request\n */\n //% help=input/button/was-pressed\n //% block=\"%button|was pressed\"\n //% blockId=buttonWasPressed\n //% parts=\"buttons\"\n //% group=\"Buttons\" advanced=true\n //% blockNamespace=input\n //% button.fieldEditor=\"gridpicker\"\n //% button.fieldOptions.width=220\n //% button.fieldOptions.columns=3\n //% weight=46 blockGap=8\n //% trackArgs=0 shim=ButtonMethods::wasPressed\n wasPressed(): boolean;\n\n /**\n * Gets the component identifier for the buton\n */\n //% shim=ButtonMethods::id\n id(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "test.ts": "" }, @@ -768,14 +769,14 @@ "music.ts": "enum Note {\n //% blockIdentity=music.noteFrequency enumval=262\n C = 262,\n //% block=C#\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F = 349,\n //% block=F#\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G = 392,\n //% block=G#\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B = 494,\n //% blockIdentity=music.noteFrequency enumval=131\n C3 = 131,\n //% block=C#3\n //% blockIdentity=music.noteFrequency enumval=139\n CSharp3 = 139,\n //% blockIdentity=music.noteFrequency enumval=147\n D3 = 147,\n //% blockIdentity=music.noteFrequency enumval=156\n Eb3 = 156,\n //% blockIdentity=music.noteFrequency enumval=165\n E3 = 165,\n //% blockIdentity=music.noteFrequency enumval=175\n F3 = 175,\n //% block=F#3\n //% blockIdentity=music.noteFrequency enumval=185\n FSharp3 = 185,\n //% blockIdentity=music.noteFrequency enumval=196\n G3 = 196,\n //% block=G#3\n //% blockIdentity=music.noteFrequency enumval=208\n GSharp3 = 208,\n //% blockIdentity=music.noteFrequency enumval=220\n A3 = 220,\n //% blockIdentity=music.noteFrequency enumval=233\n Bb3 = 233,\n //% blockIdentity=music.noteFrequency enumval=247\n B3 = 247,\n //% blockIdentity=music.noteFrequency enumval=262\n C4 = 262,\n //% block=C#4\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp4 = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D4 = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb4 = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E4 = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F4 = 349,\n //% block=F#4\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp4 = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G4 = 392,\n //% block=G#4\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp4 = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A4 = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb4 = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B4 = 494,\n //% blockIdentity=music.noteFrequency enumval=523\n C5 = 523,\n //% block=C#5\n //% blockIdentity=music.noteFrequency enumval=555\n CSharp5 = 555,\n //% blockIdentity=music.noteFrequency enumval=587\n D5 = 587,\n //% blockIdentity=music.noteFrequency enumval=622\n Eb5 = 622,\n //% blockIdentity=music.noteFrequency enumval=659\n E5 = 659,\n //% blockIdentity=music.noteFrequency enumval=698\n F5 = 698,\n //% block=F#5\n //% blockIdentity=music.noteFrequency enumval=740\n FSharp5 = 740,\n //% blockIdentity=music.noteFrequency enumval=784\n G5 = 784,\n //% block=G#5\n //% blockIdentity=music.noteFrequency enumval=831\n GSharp5 = 831,\n //% blockIdentity=music.noteFrequency enumval=880\n A5 = 880,\n //% blockIdentity=music.noteFrequency enumval=932\n Bb5 = 932,\n //% blockIdentity=music.noteFrequency enumval=988\n B5 = 988,\n}\n\nenum BeatFraction {\n //% block=1\n Whole = 1,\n //% block=\"1/2\"\n Half = 2,\n //% block=\"1/4\"\n Quarter = 4,\n //% block=\"1/8\"\n Eighth = 8,\n //% block=\"1/16\"\n Sixteenth = 16,\n //% block=\"2\"\n Double = 32,\n //% block=\"4\",\n Breve = 64,\n //% block=\"1/3\",\n Triplet = 128\n}\n\nnamespace music {\n\n let beatsPerMinute: number;\n\n /**\n * Play a tone.\n * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n */\n //% help=music/ring-tone\n //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n //% parts=\"headphone\" trackArgs=0\n //% blockNamespace=music inBasicCategory=true\n //% weight=75 blockGap=8\n //% group=\"Tone\"\n export function ringTone(frequency: number) {\n playTone(frequency, 0);\n }\n\n /**\n * Rest, or play silence, for some time (in milliseconds).\n * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n */\n //% help=music/rest\n //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n //% parts=\"headphone\" trackArgs=0\n //% blockNamespace=music\n //% weight=74\n //% group=\"Tone\"\n export function rest(ms: number) {\n playTone(0, Math.max(ms, 20));\n }\n\n function init() {\n if (!beatsPerMinute) beatsPerMinute = 120;\n }\n\n /**\n * Return the duration of a beat in milliseconds (the beat fraction).\n * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n */\n //% help=music/beat\n //% blockId=device_beat block=\"%fraction|beat\"\n //% weight=9 blockGap=8\n //% group=\"Tempo\"\n export function beat(fraction?: BeatFraction): number {\n init();\n if (fraction == null) fraction = BeatFraction.Whole;\n let beat = 60000 / beatsPerMinute;\n switch (fraction) {\n case BeatFraction.Half: beat /= 2; break;\n case BeatFraction.Quarter: beat /= 4; break;\n case BeatFraction.Eighth: beat /= 8; break;\n case BeatFraction.Sixteenth: beat /= 16; break;\n case BeatFraction.Double: beat *= 2; break;\n case BeatFraction.Breve: beat *= 4; break;\n case BeatFraction.Triplet: beat /= 3; break;\n }\n return beat >> 0;\n }\n\n /**\n * Return the tempo in beats per minute (bpm).\n * Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.\n */\n //% help=music/tempo\n //% blockId=device_tempo block=\"tempo (bpm)\"\n //% weight=64\n //% group=\"Tempo\"\n export function tempo(): number {\n init();\n return beatsPerMinute;\n }\n\n /**\n * Change the tempo up or down by some amount of beats per minute (bpm).\n * @param bpm The change in beats per minute to the tempo, eg: 20\n */\n //% help=music/change-tempo-by weight=37\n //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n //% weight=66 blockGap=8\n //% group=\"Tempo\"\n export function changeTempoBy(bpm: number): void {\n init();\n setTempo(beatsPerMinute + bpm);\n }\n\n /**\n * Set the tempo a number of beats per minute (bpm).\n * @param bpm The new tempo in beats per minute, eg: 120\n */\n //% help=music/set-tempo\n //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n //% bpm.min=4 bpm.max=400\n //% weight=65 blockGap=8\n //% group=\"Tempo\"\n export function setTempo(bpm: number): void {\n init();\n if (bpm > 0) {\n beatsPerMinute = Math.max(1, bpm >> 0);\n }\n }\n}\n", "ns.ts": "\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Sounds\", \"Melody\", \"Tone\", \"Volume\", \"Tempo\"]'\nnamespace music {\n}", "piano.ts": "namespace music {\n /**\n * Get the frequency of a note.\n * @param name the note name, eg: Note.C\n */\n //% weight=1 help=music/note-frequency\n //% blockId=device_note block=\"%note\"\n //% shim=TD_ID\n //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n //% note.fieldEditor=\"note\" note.defl=\"262\"\n //% note.fieldOptions.decompileLiterals=true\n //% useEnumVal=1\n //% weight=10 blockGap=8\n //% group=\"Tone\"\n export function noteFrequency(name: Note): number {\n return name;\n }\n}", - "pxt.json": "{\n \"name\": \"music\",\n \"description\": \"The music library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"music.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"melodies.ts\",\n \"music.ts\",\n \"piano.ts\",\n \"ns.ts\",\n \"headphone.svg\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"music\",\n \"description\": \"The music library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"music.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"melodies.ts\",\n \"music.ts\",\n \"piano.ts\",\n \"ns.ts\",\n \"headphone.svg\",\n \"pxtparts.json\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"headphone\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"headphone.svg\",\n \"width\": 142,\n \"height\": 180,\n \"pinDistance\": 20,\n \"pinLocations\": [\n {\n \"x\": 17,\n \"y\": 11\n },\n {\n \"x\": 55,\n \"y\": 50\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"D3\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [0]\n },\n {\n \"pinIndices\": [1]\n }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace music {\n\n /**\n * Play a tone through the speaker for some amount of time.\n * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n */\n //% help=music/play-tone\n //% blockId=music_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n //% parts=\"headphone\" async\n //% blockNamespace=music\n //% weight=76 blockGap=8 shim=music::playTone\n function playTone(frequency: int32, ms: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "test.ts": "for(let i = 1000; i > 0; i -= 50)\n music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n music.playTone(440, i)\n" }, "serial": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate57600 = 57600,\n //% block=38400\n BaudRate38400 = 38400,\n //% block=31250\n BaudRate31250 = 31250,\n //% block=28800\n BaudRate28800 = 28800,\n //% block=19200\n BaudRate19200 = 19200,\n //% block=14400\n BaudRate14400 = 14400,\n //% block=9600\n BaudRate9600 = 9600,\n //% block=4800\n BaudRate4800 = 4800,\n //% block=2400\n BaudRate2400 = 2400,\n //% block=1200\n BaudRate1200 = 1200,\n //% block=300\n BaudRate300 = 300,\n }\n\n\n declare const enum SerialEvent {\n //% block=\"data received\"\n DataReceived = 4, // CODAL_SERIAL_EVT_DATA_RECEIVED\n //% block=\"rx buffer full\"\n RxBufferFull = 3, // CODAL_SERIAL_EVT_RX_FULL\n }\n\n\n declare const enum Delimiters {\n //% block=\"new line (\\n)\"\n NewLine = 10,\n //% block=\",\"\n Comma = 44,\n //% block=\"$\"\n Dollar = 36,\n //% block=\":\"\n Colon = 58,\n //% block=\".\"\n Fullstop = 46,\n //% block=\"#\"\n Hash = 35,\n //% block=\"carriage return (\\r)\"\n CarriageReturn = 13,\n //% block=\"space\"\n Space = 32,\n //% block=\"tab (\\t)\"\n Tab = 9,\n //% block=\"|\"\n Pipe = 124,\n //% block=\";\"\n SemiColon = 59,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"serial\",\n \"description\": \"UART communication\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"serial-target.h\",\n \"serial-common.h\",\n \"serial-target.cpp\",\n \"serial-common.cpp\",\n \"serial-target.ts\",\n \"serial.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"serial\",\n \"description\": \"UART communication\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"serial-target.h\",\n \"serial-common.h\",\n \"serial-target.cpp\",\n \"serial-common.cpp\",\n \"serial-target.ts\",\n \"serial.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "serial-common.cpp": "#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace STMSerialDeviceMethods {\n/**\n * Sets the size of the RX buffer in bytes\n */\n//%\nvoid setRxBufferSize(Serial::STMSerialDevice device, uint8_t size) {\n device->setRxBufferSize(size);\n}\n\n/**\n * Sets the size of the TX buffer in bytes\n */\n//%\nvoid setTxBufferSize(Serial::STMSerialDevice device, uint8_t size) {\n device->setTxBufferSize(size);\n}\n\n/**\nSet the baud rate of the serial port\n*/\n//%\nvoid setBaudRate(Serial::STMSerialDevice device, BaudRate rate) {\n device->setBaudRate((int)rate);\n}\n\n/**\n * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n */\n//%\nint read(Serial::STMSerialDevice device) {\n return device->read();\n}\n\n/**\n * Read the buffered received data as a buffer\n */\n//%\nBuffer readBuffer(Serial::STMSerialDevice device) {\n return device->readBuffer();\n}\n\n/**\n * Send a buffer across the serial connection.\n */\n//%\nvoid writeBuffer(Serial::STMSerialDevice device, Buffer buffer) {\n device->writeBuffer(buffer);\n}\n\n/**\n * Register code when a serial event occurs\n */\n//%\nvoid onEvent(Serial::STMSerialDevice device, SerialEvent event, Action handler) {\n device->onEvent(event, handler);\n}\n\n/**\n * Registers code when a delimiter is received\n **/\n//%\nvoid onDelimiterReceived(Serial::STMSerialDevice device, Delimiters delimiter, Action handler) {\n device->onDelimiterReceived(delimiter, handler);\n}\n\n/**\n * Attach serial output to console\n *\n */\n//%\nvoid attachToConsole(Serial::STMSerialDevice device) {\n return;\n}\n\n} // namespace STMSerialDeviceMethods\n", "serial-common.h": "#pragma once\n#include \"pxt.h\"\n#include \"serial-target.h\"\n\nenum class BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate57600 = 57600,\n //% block=38400\n BaudRate38400 = 38400,\n //% block=31250\n BaudRate31250 = 31250,\n //% block=28800\n BaudRate28800 = 28800,\n //% block=19200\n BaudRate19200 = 19200,\n //% block=14400\n BaudRate14400 = 14400,\n //% block=9600\n BaudRate9600 = 9600,\n //% block=4800\n BaudRate4800 = 4800,\n //% block=2400\n BaudRate2400 = 2400,\n //% block=1200\n BaudRate1200 = 1200,\n //% block=300\n BaudRate300 = 300\n};\n\nenum class SerialEvent {\n //% block=\"data received\"\n DataReceived = CODAL_SERIAL_EVT_DATA_RECEIVED,\n //% block=\"rx buffer full\"\n RxBufferFull = CODAL_SERIAL_EVT_RX_FULL\n};\n\nenum class Delimiters {\n //% block=\"new line (\\n)\"\n NewLine = 10,\n //% block=\",\"\n Comma = 44,\n //% block=\"$\"\n Dollar = 36,\n //% block=\":\"\n Colon = 58,\n //% block=\".\"\n Fullstop = 46,\n //% block=\"#\"\n Hash = 35,\n //% block=\"carriage return (\\r)\"\n CarriageReturn = 13,\n //% block=\"space\"\n Space = 32,\n //% block=\"tab (\\t)\"\n Tab = 9,\n //% block=\"|\"\n Pipe = 124,\n //% block=\";\"\n SemiColon = 59,\n};\n\n", "serial-target.cpp": "#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace Serial {\n\nstatic STMSerialDevice serialDevices(NULL);\n/**\n * Opens a Serial communication driver\n */\n//%\nSTMSerialDevice internalCreateSerialDevice(DigitalInOutPin tx, DigitalInOutPin rx, int id) {\n auto dev = serialDevices;\n while (dev) {\n if (dev->matchPins(tx, rx))\n return dev;\n dev = dev->next;\n }\n\n // allocate new one\n auto ser = new CodalSTMSerialDeviceProxy(tx, rx, id);\n ser->next = serialDevices;\n serialDevices = ser;\n return ser;\n}\n\n} // namespace Serial\n\nnamespace STMSerialDeviceMethods {\n\n/**\n */\n//%\nvoid redirect(Serial::STMSerialDevice device, DigitalInOutPin tx, DigitalInOutPin rx, BaudRate rate) {\n device->redirect(tx, rx, rate);\n}\n\n} // namespace STMSerialDeviceMethods\n", @@ -788,7 +789,7 @@ "README.md": "# lcd\n\nPorted from STM32 lcd Support.\n", "lcd.cpp": "#include \"pxt.h\"\n#include \"target_lcd.h\"\n\nnamespace pxt {\nSINGLETON(WLCD);\n}\n\nnamespace lcd {\nuint8_t unpackR(uint32_t rgb) {\n uint8_t r = (rgb >> 16) & 0xFF;\n return r;\n}\nuint8_t unpackG(uint32_t rgb) {\n uint8_t g = (rgb >> 8) & 0xFF;\n return g;\n}\nuint8_t unpackB(uint32_t rgb) {\n uint8_t b = (rgb >> 0) & 0xFF;\n return b;\n}\n\n/**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"LCD_SET_CURSOR\"\n//% block=\"set cursor position |at x %x|y %y\"\n//% weight=89\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid setCursor(uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n//% blockId=\"LCD_SHOW_NUMBER\"\n//% block=\"show number %n\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowNumber(int n) {\n getWLCD()->lcd.print(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n//% blockId=\"LCD_SHOW_STRING\"\n//% block=\"show string %s\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowString(String s) {\n getWLCD()->lcd.print(s->getUTF8Data());\n}\n\n/**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n//% blockId=\"LCD_SHOW_VALUE\"\n//% block=\"show value %name = %value\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid ShowValue(String name, int value) {\n getWLCD()->lcd.print(name->getUTF8Data());\n getWLCD()->lcd.print(':');\n getWLCD()->lcd.print(value);\n}\n\n/**\n * Clear all display content\n */\n//% blockId=\"LCD_CLEAR\"\n//% block=\"clear screen\"\n//% weight=85\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid clear() {\n getWLCD()->lcd.clear();\n}\n\n/**\n * Set lcd backlight color\n *\n * @param rgb RGB color of the backlight LED\n */\n//% blockId=\"LCD_BACKLIGHT_COLOR\"\n//% block=\"set backlight color %rgb=colorNumberPicker\"\n//% weight=69\n//% blockGap=8\n//% group=\"Backlight\"\n//% parts=lcd trackArgs=0\nvoid SetBacklightColor(uint32_t rgb) {\n uint8_t r = unpackR(rgb);\n uint8_t g = unpackG(rgb);\n uint8_t b = unpackB(rgb);\n getWLCD()->lcd.setRGB(r, g, b);\n}\n\n/**\n * Turn on lcd backlight\n */\n//% blockId=\"LCD_BACKLIGHT_ON\"\n//% block=\"turn on backlight\"\n//% group=\"Backlight\"\n//% weight=71\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid BacklightOn() {\n getWLCD()->lcd.setColorWhite();\n}\n\n/**\n * Turn off lcd backlight\n */\n//% blockId=\"LCD_BACKLIGHT_OFF\"\n//% block=\"turn off backlight\"\n//% group=\"Backlight\"\n//% weight=70\n//% blockGap=8\n//% parts=lcd trackArgs=0\nvoid BacklightOff() {\n getWLCD()->lcd.setColorAll();\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"LCD_SHOW_NUMBER_AT_POS\"\n//% block=\"show number %n|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid ShowNumberAtPos(int n, uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n ShowNumber(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n//% blockId=\"LCD_SHOW_STRING_AT_POS\"\n//% block=\"show string %s|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd trackArgs=0\nvoid ShowStringAtPos(String s, uint8_t x, uint8_t y) {\n getWLCD()->lcd.setCursor(x, y);\n ShowString(s);\n}\n} // namespace lcd", "ns.ts": "/**\n * Character lcd support\n */\n//% icon=\"\\uf0ae\" color=\"#219E42\" blockGap=8\n//% groups='[\"Display\", \"Configuration\"]'\nnamespace lcd {\n\n}", - "pxt.json": "{\n \"name\": \"lcd\",\n \"description\": \"Support for I2C Characeter LCD display with RGB backlight\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"lcd\",\n \"description\": \"Support for I2C Characeter LCD display with RGB backlight\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"lcd\": {\n \"simulationBehavior\": \"lcd\",\n \"visual\": {\n \"builtIn\": \"lcd\",\n \"width\": 322.7900085449219,\n \"height\": 129.2734832763672,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 25,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 40,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 55,\n \"y\": 8.037069860858837\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"assembly\": [\n { \"part\": true },\n { \"pinIndices\": [0] },\n { \"pinIndices\": [1] },\n { \"pinIndices\": [2, 3] }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace lcd {\n\n /**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"LCD_SET_CURSOR\"\n //% block=\"set cursor position |at x %x|y %y\"\n //% weight=89\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::setCursor\n function setCursor(x: uint8, y: uint8): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n //% blockId=\"LCD_SHOW_NUMBER\"\n //% block=\"show number %n\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowNumber\n function ShowNumber(n: int32): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n //% blockId=\"LCD_SHOW_STRING\"\n //% block=\"show string %s\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowString\n function ShowString(s: string): void;\n\n /**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n //% blockId=\"LCD_SHOW_VALUE\"\n //% block=\"show value %name = %value\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::ShowValue\n function ShowValue(name: string, value: int32): void;\n\n /**\n * Clear all display content\n */\n //% blockId=\"LCD_CLEAR\"\n //% block=\"clear screen\"\n //% weight=85\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::clear\n function clear(): void;\n\n /**\n * Set lcd backlight color\n *\n * @param rgb RGB color of the backlight LED\n */\n //% blockId=\"LCD_BACKLIGHT_COLOR\"\n //% block=\"set backlight color %rgb=colorNumberPicker\"\n //% weight=69\n //% blockGap=8\n //% group=\"Backlight\"\n //% parts=lcd trackArgs=0 shim=lcd::SetBacklightColor\n function SetBacklightColor(rgb: uint32): void;\n\n /**\n * Turn on lcd backlight\n */\n //% blockId=\"LCD_BACKLIGHT_ON\"\n //% block=\"turn on backlight\"\n //% group=\"Backlight\"\n //% weight=71\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::BacklightOn\n function BacklightOn(): void;\n\n /**\n * Turn off lcd backlight\n */\n //% blockId=\"LCD_BACKLIGHT_OFF\"\n //% block=\"turn off backlight\"\n //% group=\"Backlight\"\n //% weight=70\n //% blockGap=8\n //% parts=lcd trackArgs=0 shim=lcd::BacklightOff\n function BacklightOff(): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"LCD_SHOW_NUMBER_AT_POS\"\n //% block=\"show number %n|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::ShowNumberAtPos\n function ShowNumberAtPos(n: int32, x: uint8, y: uint8): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n //% blockId=\"LCD_SHOW_STRING_AT_POS\"\n //% block=\"show string %s|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd trackArgs=0 shim=lcd::ShowStringAtPos\n function ShowStringAtPos(s: string, x: uint8, y: uint8): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_lcd.h": "#include \"pxt.h\"\n#include \"STM32I2C.h\"\n#include \"rgb_lcd.h\"\n\nnamespace pxt {\nclass WLCD {\n public:\n codal::STM32I2C i2c;\n codal::rgb_lcd lcd;\n WLCD() : i2c(*LOOKUP_PIN(SDA), *LOOKUP_PIN(SCL)), lcd(i2c, 16, 2) { lcd.init(); }\n};\n} // namespace pxt" @@ -797,7 +798,7 @@ "accelerometer.cpp": "#include \"CoordinateSystem.h\"\n#include \"I2C.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n#include \"target_accelerometer.h\"\n#include \"target_compass.h\"\n#include \"target_gyroscope.h\"\n\nenum class Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n};\n\nenum class Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n};\n\nenum class AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8\n};\n\nenum class Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = ACCELEROMETER_EVT_SHAKE,\n /**\n * Raised when the device tilts up\n */\n //% block=\"tilt up\"\n TiltUp = ACCELEROMETER_EVT_TILT_UP,\n /**\n * Raised when the device tilts down\n */\n //% block=\"tilt down\"\n TiltDown = ACCELEROMETER_EVT_TILT_DOWN,\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = ACCELEROMETER_EVT_TILT_LEFT,\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = ACCELEROMETER_EVT_TILT_RIGHT,\n /**\n * Raised when the screen faces up\n */\n //% block=\"face up\"\n FaceUp = ACCELEROMETER_EVT_FACE_UP,\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"face down\"\n FaceDown = ACCELEROMETER_EVT_FACE_DOWN,\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = ACCELEROMETER_EVT_FREEFALL,\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = ACCELEROMETER_EVT_3G,\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = ACCELEROMETER_EVT_6G,\n /**\n * Raised when a 8G shock is detected\n */\n //% block=\"8g\"\n EightG = ACCELEROMETER_EVT_8G\n};\n\nnamespace pxt {\n\nSINGLETON(WAccel);\nSINGLETON(WCompas);\nSINGLETON(WGyro);\n} // namespace pxt\n\nnamespace input {\n/**\n * Do something when a gesture happens (like shaking the board).\n * @param gesture the type of gesture to track, eg: Gesture.Shake\n * @param body code to run when gesture is raised\n */\n//% help=input/on-gesture\n//% blockId=device_gesture_event block=\"on |%NAME\"\n//% parts=\"accelerometer\"\n//% gesture.fieldEditor=\"gridpicker\"\n//% gesture.fieldOptions.width=220\n//% gesture.fieldOptions.columns=3\n//% group=\"Movement\"\n//% weight=92 blockGap=12\nvoid onGesture(Gesture gesture, Action body) {\n auto acc = getWAccel()->acc;\n acc->requestUpdate();\n int gi = (int)gesture;\n if (gi == ACCELEROMETER_EVT_3G && acc->getRange() < 3)\n acc->setRange(4);\n else if ((gi == ACCELEROMETER_EVT_6G || gi == ACCELEROMETER_EVT_8G) && acc->getRange() < 6)\n acc->setRange(8);\n registerWithDal(DEVICE_ID_GESTURE, gi, body);\n}\n\nint getAccelerationStrength() {\n auto acc = getWAccel()->acc;\n float x = acc->getX();\n float y = acc->getY();\n float z = acc->getZ();\n return (int)sqrtf(x * x + y * y + z * z);\n}\n\n/**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n * x=0, y=0 and z=-1023)\n * @param dimension TODO\n */\n//% help=input/acceleration\n//% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n//% parts=\"accelerometer\"\n//% dimension.fieldEditor=\"gridpicker\"\n//% dimension.fieldOptions.width=180\n//% dimension.fieldOptions.columns=2\n//% group=\"Movement\"\n//% weight=42 blockGap=8\nint acceleration(Dimension dimension) {\n switch (dimension) {\n case Dimension::X:\n return getWAccel()->acc->getX();\n case Dimension::Y:\n return getWAccel()->acc->getY();\n case Dimension::Z:\n return getWAccel()->acc->getZ();\n case Dimension::Strength:\n return getAccelerationStrength();\n }\n return 0;\n}\n\n/**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n//% help=input/rotation\n//% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n//% parts=\"accelerometer\"\n//% group=\"Movement\"\n//% weight=38\nint rotation(Rotation kind) {\n switch (kind) {\n case Rotation::Pitch:\n return getWAccel()->acc->getPitch();\n case Rotation::Roll:\n return getWAccel()->acc->getRoll();\n }\n return 0;\n}\n\n/**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n//% help=input/set-accelerometer-range\n//% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n//% weight=5 advanced=true\n//% parts=\"accelerometer\"\n//% group=\"Movement\"\n//% weight=15 blockGap=8\nvoid setAccelerometerRange(AcceleratorRange range) {\n getWAccel()->acc->setRange((int)range);\n}\n\n/**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the\n * simulator.\n * @param dimension TODO\n */\n//% help=input/magnetic-force weight=51\n//% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"compass\"\nint magneticForce(Dimension dimension) {\n if (!getWCompas()->magnetometer->isCalibrated())\n getWCompas()->magnetometer->calibrate();\n\n switch (dimension) {\n case Dimension::X:\n return getWCompas()->magnetometer->getX();\n case Dimension::Y:\n return getWCompas()->magnetometer->getY();\n case Dimension::Z:\n return getWCompas()->magnetometer->getZ();\n case Dimension::Strength:\n return getWCompas()->magnetometer->getFieldStrength();\n }\n return 0;\n}\n\n/**\n * Get the current compass heading in degrees.\n */\n//% help=input/compass-heading\n//% weight=56\n//% blockId=device_heading block=\"compass heading (°)\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"compass\"\nint compassHeading() {\n return getWCompas()->magnetometer->heading();\n}\n\n/**\n * Get the angular acceleration. This function is not supported in the simulator.\n * @param dimension TODO\n */\n//% help=input/gyroscopic-force weight=51\n//% blockId=device_get_gyroscopic_force block=\"angular acceleration|%NAME\"\n//% group=\"Movement\" blockGap=8\n//% parts=\"gyroscope\"\nint gyroscopicForce(Dimension dimension) {\n switch (dimension) {\n case Dimension::X:\n return getWGyro()->gyroscope->getX();\n case Dimension::Y:\n return getWGyro()->gyroscope->getY();\n case Dimension::Z:\n return getWGyro()->gyroscope->getZ();\n case Dimension::Strength:\n return 0; // getWGyro()->gyroscope.getStrength();\n }\n return 0;\n}\n\n} // namespace input\n", "axis.h": "// Override in target to change inversion of axis\n\n#define ACC_SYSTEM SIMPLE_CARTESIAN\n#define ACC_UPSIDEDOWN true\n#define ACC_ROTATION COORDINATE_SPACE_ROTATED_180", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n }\n\n\n declare const enum Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n }\n\n\n declare const enum AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8,\n }\n\n\n declare const enum Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = 11, // ACCELEROMETER_EVT_SHAKE\n /**\n * Raised when the device tilts up\n */\n //% block=\"tilt up\"\n TiltUp = 1, // ACCELEROMETER_EVT_TILT_UP\n /**\n * Raised when the device tilts down\n */\n //% block=\"tilt down\"\n TiltDown = 2, // ACCELEROMETER_EVT_TILT_DOWN\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = 3, // ACCELEROMETER_EVT_TILT_LEFT\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = 4, // ACCELEROMETER_EVT_TILT_RIGHT\n /**\n * Raised when the screen faces up\n */\n //% block=\"face up\"\n FaceUp = 5, // ACCELEROMETER_EVT_FACE_UP\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"face down\"\n FaceDown = 6, // ACCELEROMETER_EVT_FACE_DOWN\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = 7, // ACCELEROMETER_EVT_FREEFALL\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = 8, // ACCELEROMETER_EVT_3G\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = 9, // ACCELEROMETER_EVT_6G\n /**\n * Raised when a 8G shock is detected\n */\n //% block=\"8g\"\n EightG = 10, // ACCELEROMETER_EVT_8G\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"accelerometer---lsm6dsl\",\n \"description\": \"The accelerometer library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"accelerometer.cpp\",\n \"target_accelerometer.h\",\n \"target_compass.h\",\n \"target_gyroscope.h\",\n \"axis.h\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"accelerometer---lsm6dsl\",\n \"description\": \"The accelerometer library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"accelerometer.cpp\",\n \"target_accelerometer.h\",\n \"target_compass.h\",\n \"target_gyroscope.h\",\n \"axis.h\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Do something when a gesture happens (like shaking the board).\n * @param gesture the type of gesture to track, eg: Gesture.Shake\n * @param body code to run when gesture is raised\n */\n //% help=input/on-gesture\n //% blockId=device_gesture_event block=\"on |%NAME\"\n //% parts=\"accelerometer\"\n //% gesture.fieldEditor=\"gridpicker\"\n //% gesture.fieldOptions.width=220\n //% gesture.fieldOptions.columns=3\n //% group=\"Movement\"\n //% weight=92 blockGap=12 shim=input::onGesture\n function onGesture(gesture: Gesture, body: () => void): void;\n\n /**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n * x=0, y=0 and z=-1023)\n * @param dimension TODO\n */\n //% help=input/acceleration\n //% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n //% parts=\"accelerometer\"\n //% dimension.fieldEditor=\"gridpicker\"\n //% dimension.fieldOptions.width=180\n //% dimension.fieldOptions.columns=2\n //% group=\"Movement\"\n //% weight=42 blockGap=8 shim=input::acceleration\n function acceleration(dimension: Dimension): int32;\n\n /**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n //% help=input/rotation\n //% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n //% parts=\"accelerometer\"\n //% group=\"Movement\"\n //% weight=38 shim=input::rotation\n function rotation(kind: Rotation): int32;\n\n /**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n //% help=input/set-accelerometer-range\n //% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n //% weight=5 advanced=true\n //% parts=\"accelerometer\"\n //% group=\"Movement\"\n //% weight=15 blockGap=8 shim=input::setAccelerometerRange\n function setAccelerometerRange(range: AcceleratorRange): void;\n\n /**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the\n * simulator.\n * @param dimension TODO\n */\n //% help=input/magnetic-force weight=51\n //% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"compass\" shim=input::magneticForce\n function magneticForce(dimension: Dimension): int32;\n\n /**\n * Get the current compass heading in degrees.\n */\n //% help=input/compass-heading\n //% weight=56\n //% blockId=device_heading block=\"compass heading (°)\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"compass\" shim=input::compassHeading\n function compassHeading(): int32;\n\n /**\n * Get the angular acceleration. This function is not supported in the simulator.\n * @param dimension TODO\n */\n //% help=input/gyroscopic-force weight=51\n //% blockId=device_get_gyroscopic_force block=\"angular acceleration|%NAME\"\n //% group=\"Movement\" blockGap=8\n //% parts=\"gyroscope\" shim=input::gyroscopicForce\n function gyroscopicForce(dimension: Dimension): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_accelerometer.h": "#include \"LSM6DSL_Accelerometer.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\n\n// Wrapper classes\nclass WAccel {\n private:\n CODAL_I2C *i2c;\n codal::CoordinateSpace coordinateSpace;\n\n public:\n codal::Accelerometer *acc = nullptr;\n\n WAccel()\n : i2c(getI2C(LOOKUP_PIN(LSM6DSL_SDA), LOOKUP_PIN(LSM6DSL_SCL))),\n coordinateSpace(SIMPLE_CARTESIAN, true, COORDINATE_SPACE_ROTATED_180),\n acc(new codal::LSM6DSL_Accelerometer(i2c, 0xD4, coordinateSpace)) {}\n\n ~WAccel() { delete acc; }\n};\n} // namespace pxt", "target_compass.h": "#include \"LIS3MDL_Magnetometer.h\"\n#include \"Pin.h\"\n#include \"axis.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\n\n// Wrapper classes\nclass WCompas {\n private:\n CODAL_I2C *i2c;\n codal::CoordinateSpace coordinateSpace;\n\n public:\n codal::Compass *magnetometer;\n\n WCompas()\n : i2c(getI2C(LOOKUP_PIN(LSM6DSL_SDA), LOOKUP_PIN(LSM6DSL_SCL))),\n coordinateSpace(codal::CoordinateSystem::SIMPLE_CARTESIAN),\n magnetometer(new codal::LIS3MDL_Magnetometer(i2c, 0x3C, coordinateSpace)) {\n magnetometer->configure();\n }\n\n ~WCompas() { delete magnetometer; }\n};\n} // namespace pxt", @@ -807,14 +808,14 @@ "barometer---lps22hb": { "barometer.cpp": "#include \"pxt.h\"\n#include \"target_barometer.h\"\n\nenum class PressureCondition {\n //% block=\"high\"\n High = SENSOR_THRESHOLD_HIGH,\n //% block=\"low\"\n Low = SENSOR_THRESHOLD_LOW\n};\n\nenum class PressureUnit {\n //% block=\"hPa\"\n HectoPascal,\n //% block=\"mBar\"\n mBar\n};\n\nnamespace pxt {\nSINGLETON(WBarometer);\n}\n\nnamespace input {\n\n/**\n * Run some code when the pressure changes from high to low, or from low to high.\n * @param condition the condition, low or high, the event triggers on\n * @param pressure the pressure at which this event happens, eg: 1013.25\n * @param unit the unit of the pressure\n */\n//% blockId=input_on_pressure_condition_changed block=\"on pressure %condition|at %pressure |%unit\"\n//% help=input/on-pressure-condition-changed blockExternalInputs=0\n//% parts=\"pressure\"\n//% group=\"Pressure\"\n//% weight=76\nvoid onPressureConditionChanged(PressureCondition condition, int pressure, PressureUnit unit, Action handler) {\n auto sensor = getWBarometer()->sensor;\n sensor->updateSample();\n\n float t = pressure;\n\n if (condition == PressureCondition::Low)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the pressure.\n */\n//% help=input/pressure\n//% blockId=device_pressure block=\"pressure in %unit\"\n//% parts=\"pressure\"\n//% group=\"Pressure\"\n//% weight=26\nint pressure(PressureUnit unit) {\n return (int)getWBarometer()->sensor->getValue();\n}\n} // namespace input", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum PressureCondition {\n //% block=\"high\"\n High = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"low\"\n Low = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum PressureUnit {\n //% block=\"hPa\"\n HectoPascal = 0,\n //% block=\"mBar\"\n mBar = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"barometer---lps22hb\",\n \"description\": \"A barometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"barometer.cpp\",\n \"target_barometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"barometer---lps22hb\",\n \"description\": \"A barometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"barometer.cpp\",\n \"target_barometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the pressure changes from high to low, or from low to high.\n * @param condition the condition, low or high, the event triggers on\n * @param pressure the pressure at which this event happens, eg: 1013.25\n * @param unit the unit of the pressure\n */\n //% blockId=input_on_pressure_condition_changed block=\"on pressure %condition|at %pressure |%unit\"\n //% help=input/on-pressure-condition-changed blockExternalInputs=0\n //% parts=\"pressure\"\n //% group=\"Pressure\"\n //% weight=76 shim=input::onPressureConditionChanged\n function onPressureConditionChanged(condition: PressureCondition, pressure: int32, unit: PressureUnit, handler: () => void): void;\n\n /**\n * Get the pressure.\n */\n //% help=input/pressure\n //% blockId=device_pressure block=\"pressure in %unit\"\n //% parts=\"pressure\"\n //% group=\"Pressure\"\n //% weight=26 shim=input::pressure\n function pressure(unit: PressureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_barometer.h": "#include \"LPS22HB_Pressure.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WBarometer {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::LPS22HB_Pressure *sensor;\n\n WBarometer()\n : i2c(getI2C(LOOKUP_PIN(LPS22HB_SDA), LOOKUP_PIN(LPS22HB_SCL))),\n sensor(new codal::LPS22HB_Pressure(DEVICE_ID_PRESSURE, i2c, 0xBA, 1023)) {}\n\n ~WBarometer() { delete sensor; }\n};\n} // namespace pxt" }, "distance---vl53l0x": { "distance.cpp": "#include \"pxt.h\"\n#include \"target_distance.h\"\n\nenum class DistanceCondition {\n //% block=\"far\"\n Far = SENSOR_THRESHOLD_HIGH,\n //% block=\"near\"\n Near = SENSOR_THRESHOLD_LOW\n};\n\nenum class DistanceUnit {\n //% block=\"mm\"\n Millimeter,\n //% block=\"cm\"\n Centimeter,\n //% block=\"dm\"\n Decimeter,\n //% block=\"m\"\n Meter\n};\n\nnamespace pxt {\nSINGLETON(WDistance);\n}\n\nnamespace input {\n\n/**\n * Run some code when the distance changes from near to far, or from far to near.\n * @param condition the condition, far or near, the event triggers on\n * @param distance the distance at which this event happens, eg: 15\n * @param unit the unit of the distance\n */\n//% blockId=input_on_distance_condition_changed block=\"on distance %condition|at %distance|%unit\"\n//% parts=\"distance\"\n//% help=input/on-distance-condition-changed blockExternalInputs=0\n//% group=\"Distance\" weight=76\nvoid onDistanceConditionChanged(DistanceCondition condition, int distance, DistanceUnit unit, Action handler) {\n auto sensor = getWDistance()->sensor;\n sensor->updateSample();\n\n int d;\n\n switch (unit) {\n case DistanceUnit::Millimeter:\n d = distance;\n break;\n case DistanceUnit::Centimeter:\n d = distance * 10;\n break;\n case DistanceUnit::Decimeter:\n d = distance * 100;\n break;\n case DistanceUnit::Meter:\n d = distance * 1000;\n break;\n default:\n d = 0;\n break;\n }\n\n if (condition == DistanceCondition::Near)\n sensor->setLowThreshold(d);\n else\n sensor->setHighThreshold(d);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the distance.\n */\n//% help=input/distance\n//% blockId=device_distance block=\"distance in %unit\"\n//% parts=\"distance\"\n//% group=\"Distance\"\n//% weight=26\nfloat distance(DistanceUnit unit) {\n int distance = getWDistance()->sensor->getValue();\n switch (unit) {\n case DistanceUnit::Millimeter:\n return distance;\n case DistanceUnit::Centimeter:\n return distance / 10.;\n case DistanceUnit::Decimeter:\n return distance / 100.;\n case DistanceUnit::Meter:\n return distance / 1000.;\n default:\n return 0;\n }\n}\n} // namespace input", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum DistanceCondition {\n //% block=\"far\"\n Far = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"near\"\n Near = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum DistanceUnit {\n //% block=\"mm\"\n Millimeter = 0,\n //% block=\"cm\"\n Centimeter = 1,\n //% block=\"dm\"\n Decimeter = 2,\n //% block=\"m\"\n Meter = 3,\n }\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"distance---vl53l0x\",\n \"description\": \"A distance sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"distance.cpp\",\n \"target_distance.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"distance---vl53l0x\",\n \"description\": \"A distance sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"distance.cpp\",\n \"target_distance.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the distance changes from near to far, or from far to near.\n * @param condition the condition, far or near, the event triggers on\n * @param distance the distance at which this event happens, eg: 15\n * @param unit the unit of the distance\n */\n //% blockId=input_on_distance_condition_changed block=\"on distance %condition|at %distance|%unit\"\n //% parts=\"distance\"\n //% help=input/on-distance-condition-changed blockExternalInputs=0\n //% group=\"Distance\" weight=76 shim=input::onDistanceConditionChanged\n function onDistanceConditionChanged(condition: DistanceCondition, distance: int32, unit: DistanceUnit, handler: () => void): void;\n\n /**\n * Get the distance.\n */\n //% help=input/distance\n //% blockId=device_distance block=\"distance in %unit\"\n //% parts=\"distance\"\n //% group=\"Distance\"\n //% weight=26 shim=input::distance\n function distance(unit: DistanceUnit): number;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_distance.h": "#include \"VL53L0X_Distance.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WDistance {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::VL53L0X_Distance *sensor;\n\n WDistance()\n : i2c(getI2C(LOOKUP_PIN(VL53L0X_SDA), LOOKUP_PIN(VL53L0X_SCL))),\n sensor(new codal::VL53L0X_Distance(DEVICE_ID_DISTANCE, i2c, LOOKUP_PIN(VL53L0X_SHUT), 0x52, 1023, 1000)) {\n\n // The VL53L0X need time to internally initialize, but when it is done, we can reduce the samplePerdiod\n sensor->setPeriod(100);\n }\n ~WDistance() { delete sensor; }\n};\n} // namespace pxt", "test.ts": "" @@ -822,7 +823,7 @@ "thermometer---hts221": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum TemperatureCondition {\n //% block=\"hot\"\n Hot = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"cold\"\n Cold = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum TemperatureUnit {\n //% block=\"°C\"\n Celsius = 0,\n //% block=\"°F\"\n Fahrenheit = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}", - "pxt.json": "{\n \"name\": \"thermometer---hts221\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"thermometer---hts221\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n //% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n //% parts=\"thermometer\"\n //% help=input/on-temperature-condition-changed blockExternalInputs=0\n //% group=\"Temperature\" weight=76 shim=input::onTemperatureConditionChanged\n function onTemperatureConditionChanged(condition: TemperatureCondition, temperature: int32, unit: TemperatureUnit, handler: () => void): void;\n\n /**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature in %unit\"\n //% parts=\"thermometer\"\n //% group=\"Temperature\"\n //% weight=26 shim=input::temperature\n function temperature(unit: TemperatureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_thermometer.h": "#include \"HTS221_Temperature.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WTemp {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::HTS221_Temperature *sensor;\n\n WTemp()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::HTS221_Temperature(DEVICE_ID_THERMOMETER, i2c, 0xBE, 1023)) {}\n ~WTemp() { delete sensor; }\n};\n} // namespace pxt\n", "thermometer.cpp": "#include \"pxt.h\"\n#include \"target_thermometer.h\"\n\nenum class TemperatureCondition {\n //% block=\"hot\"\n Hot = SENSOR_THRESHOLD_HIGH,\n //% block=\"cold\"\n Cold = SENSOR_THRESHOLD_LOW\n};\n\nenum class TemperatureUnit {\n //% block=\"°C\"\n Celsius,\n //% block=\"°F\"\n Fahrenheit\n};\n\nnamespace pxt {\nSINGLETON(WTemp);\n}\n\nnamespace input {\n\n/**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n//% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n//% parts=\"thermometer\"\n//% help=input/on-temperature-condition-changed blockExternalInputs=0\n//% group=\"Temperature\" weight=76\nvoid onTemperatureConditionChanged(TemperatureCondition condition, int temperature, TemperatureUnit unit, Action handler) {\n auto thermo = getWTemp();\n if (!thermo)\n return;\n\n auto sensor = thermo->sensor;\n sensor->updateSample();\n\n int t = unit == TemperatureUnit::Celsius ? temperature : ((temperature - 32) * 10) / 18;\n\n if (condition == TemperatureCondition::Cold)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n//% help=input/temperature\n//% blockId=device_temperature block=\"temperature in %unit\"\n//% parts=\"thermometer\"\n//% group=\"Temperature\"\n//% weight=26\nint temperature(TemperatureUnit unit) {\n auto thermo = getWTemp();\n\n // default to -1000 if not present\n int value = (NULL != thermo) ? (int)thermo->sensor->getValue() : -1000;\n\n if (unit == TemperatureUnit::Celsius)\n return value;\n else\n return (value * 18) / 10 + 32;\n}\n} // namespace input\n" @@ -830,7 +831,7 @@ "thermometer---lps22hb": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum TemperatureCondition {\n //% block=\"hot\"\n Hot = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"cold\"\n Cold = 1, // SENSOR_THRESHOLD_LOW\n }\n\n\n declare const enum TemperatureUnit {\n //% block=\"°C\"\n Celsius = 0,\n //% block=\"°F\"\n Fahrenheit = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}", - "pxt.json": "{\n \"name\": \"thermometer---lps22hb\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"thermometer---lps22hb\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"thermometer.cpp\",\n \"target_thermometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n //% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n //% parts=\"thermometer\"\n //% help=input/on-temperature-condition-changed blockExternalInputs=0\n //% group=\"Temperature\" weight=76 shim=input::onTemperatureConditionChanged\n function onTemperatureConditionChanged(condition: TemperatureCondition, temperature: int32, unit: TemperatureUnit, handler: () => void): void;\n\n /**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature in %unit\"\n //% parts=\"thermometer\"\n //% group=\"Temperature\"\n //% weight=26 shim=input::temperature\n function temperature(unit: TemperatureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_thermometer.h": "#include \"LPS22HB_Temperature.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WTemp {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::LPS22HB_Temperature *sensor;\n\n WTemp()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::LPS22HB_Temperature(DEVICE_ID_THERMOMETER, i2c, 0xBA, 1023)) {}\n ~WTemp() { delete sensor; }\n};\n} // namespace pxt\n", "thermometer.cpp": "#include \"pxt.h\"\n#include \"target_thermometer.h\"\n\nenum class TemperatureCondition {\n //% block=\"hot\"\n Hot = SENSOR_THRESHOLD_HIGH,\n //% block=\"cold\"\n Cold = SENSOR_THRESHOLD_LOW\n};\n\nenum class TemperatureUnit {\n //% block=\"°C\"\n Celsius,\n //% block=\"°F\"\n Fahrenheit\n};\n\nnamespace pxt {\nSINGLETON(WTemp);\n}\n\nnamespace input {\n\n/**\n * Run some code when the temperature changes from hot to cold, or from cold to hot.\n * @param condition the condition, hot or cold, the event triggers on\n * @param temperature the temperature at which this event happens, eg: 15\n * @param unit the unit of the temperature\n */\n//% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n//% parts=\"thermometer\"\n//% help=input/on-temperature-condition-changed blockExternalInputs=0\n//% group=\"Temperature\" weight=76\nvoid onTemperatureConditionChanged(TemperatureCondition condition, int temperature, TemperatureUnit unit, Action handler) {\n auto thermo = getWTemp();\n if (!thermo)\n return;\n\n auto sensor = thermo->sensor;\n sensor->updateSample();\n\n int t = unit == TemperatureUnit::Celsius ? temperature : ((temperature - 32) * 10) / 18;\n\n if (condition == TemperatureCondition::Cold)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n//% help=input/temperature\n//% blockId=device_temperature block=\"temperature in %unit\"\n//% parts=\"thermometer\"\n//% group=\"Temperature\"\n//% weight=26\nint temperature(TemperatureUnit unit) {\n auto thermo = getWTemp();\n\n // default to -1000 if not present\n int value = (NULL != thermo) ? (int)thermo->sensor->getValue() : -1000;\n\n if (unit == TemperatureUnit::Celsius)\n return value;\n else\n return (value * 18) / 10 + 32;\n}\n} // namespace input\n" @@ -838,7 +839,7 @@ "hygrometer---hts221": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum HumidityCondition {\n //% block=\"wet\"\n Wet = 2, // SENSOR_THRESHOLD_HIGH\n //% block=\"dry\"\n Dry = 1, // SENSOR_THRESHOLD_LOW\n }\n\n// Auto-generated. Do not edit. Really.\n", "hygrometer.cpp": "#include \"pxt.h\"\n#include \"target_hygrometer.h\"\n\nenum class HumidityCondition {\n //% block=\"wet\"\n Wet = SENSOR_THRESHOLD_HIGH,\n //% block=\"dry\"\n Dry = SENSOR_THRESHOLD_LOW\n};\n\nnamespace pxt {\nSINGLETON(WHygrometer);\n}\n\nnamespace input {\n\n/**\n * Run some code when the humidity changes from dry to wet, or from wet to dry.\n * @param condition the condition, wet or dry, the event triggers on\n * @param humidity the humidity at which this event happens, eg: 50\n * @param unit the unit of the humidity\n */\n//% blockId=input_on_humidity_condition_changed block=\"on humidity %condition|at %humidity percent\"\n//% help=input/on-humidity-condition-changed blockExternalInputs=0\n//% parts=\"humidity\"\n//% group=\"Humidity\" weight=76\nvoid onHumidityConditionChanged(HumidityCondition condition, int humidity, Action handler) {\n auto sensor = getWHygrometer()->sensor;\n sensor->updateSample();\n\n float t = humidity; //*10.;\n\n if (condition == HumidityCondition::Dry)\n sensor->setLowThreshold(t);\n else\n sensor->setHighThreshold(t);\n registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the relative humidity in percent.\n */\n//% help=input/humidity\n//% blockId=device_humidity block=\"relative humidity in percent\"\n//% parts=\"humidity\"\n//% group=\"Humidity\"\n//% weight=26\nint humidity() {\n return (int)getWHygrometer()->sensor->getValue(); /// 10.;\n}\n} // namespace input", - "pxt.json": "{\n \"name\": \"hygrometer---hts221\",\n \"description\": \"A hygrometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hygrometer.cpp\",\n \"target_hygrometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"hygrometer---hts221\",\n \"description\": \"A hygrometer sensor driver\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hygrometer.cpp\",\n \"target_hygrometer.h\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Run some code when the humidity changes from dry to wet, or from wet to dry.\n * @param condition the condition, wet or dry, the event triggers on\n * @param humidity the humidity at which this event happens, eg: 50\n * @param unit the unit of the humidity\n */\n //% blockId=input_on_humidity_condition_changed block=\"on humidity %condition|at %humidity percent\"\n //% help=input/on-humidity-condition-changed blockExternalInputs=0\n //% parts=\"humidity\"\n //% group=\"Humidity\" weight=76 shim=input::onHumidityConditionChanged\n function onHumidityConditionChanged(condition: HumidityCondition, humidity: int32, handler: () => void): void;\n\n /**\n * Get the relative humidity in percent.\n */\n //% help=input/humidity\n //% blockId=device_humidity block=\"relative humidity in percent\"\n //% parts=\"humidity\"\n //% group=\"Humidity\"\n //% weight=26 shim=input::humidity\n function humidity(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_hygrometer.h": "#include \"HTS221_Humidity.h\"\n#include \"Sensor.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WHygrometer {\n private:\n CODAL_I2C *i2c;\n\n public:\n codal::HTS221_Humidity *sensor;\n\n WHygrometer()\n : i2c(getI2C(LOOKUP_PIN(HTS221_SDA), LOOKUP_PIN(HTS221_SCL))),\n sensor(new codal::HTS221_Humidity(DEVICE_ID_HUMIDITY, i2c, 0xBE, 1023)) {}\n\n ~WHygrometer() { delete sensor; }\n};\n} // namespace pxt" }, @@ -846,7 +847,7 @@ "SSD1306_128x64.svg": "\nimage/svg+xml\n\n\t\n\n\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\tVCC\n\n\tGND\n\n\tSCL\n\n\tSDA\n\n\t\n\t\n\t\n\t\n\t\n\tOLED 128x64 \n\n\tSSD1306 \n\n\tI2C\n\n\tblog.squix.ch\n\n", "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum PixelColor {\n //% block=\"Black\"\n Black = 0,\n //% block=\"White\"\n White = 1,\n }\n\n\n declare const enum AddressScreen {\n //% block=\"0x78\"\n x74 = 0x78,\n //% block=\"0x7A\"\n x7A = 0x7A,\n }\n\n// Auto-generated. Do not edit. Really.\n", "ns.ts": "//% color=\"#FF9933\" weight=50 icon=\"\\uf120\"\n//% groups='[\"Oled\", \"More\"]'\nnamespace oled {\n}\n", - "pxt.json": "{\n \"name\": \"oled\",\n \"description\": \"Support for OLED display based on the SSD1306\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"ns.ts\",\n \"screen.ts\",\n \"ssd1306.cpp\",\n \"target_ssd1306.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\",\n \"SSD1306_128x64.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"oled\",\n \"description\": \"Support for OLED display based on the SSD1306\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"ns.ts\",\n \"screen.ts\",\n \"ssd1306.cpp\",\n \"target_ssd1306.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\",\n \"SSD1306_128x64.svg\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"ssd1306\": {\n \"simulationBehavior\": \"ssd1306\",\n \"visual\": {\n \"builtIn\": \"ssd1306\",\n \"width\": 171.054,\n \"height\": 170.167,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 62,\n \"y\": 10.167\n },\n {\n \"x\": 77,\n \"y\": 10.167\n },\n {\n \"x\": 92,\n \"y\": 10.167\n },\n {\n \"x\": 107,\n \"y\": 10.167\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"assembly\": [\n {\n \"pinIndices\": [\n 0,\n 1,\n 2,\n 3\n ]\n }\n ]\n }\n}", "screen.ts": "/**\n * Basic screen display functionalities\n */\n//% color=\"#FF9933\" weight=50 icon=\"\\uf120\"\n//% groups='[\"Oled\", \"More\"]'\nnamespace oled {\n const textOffset = 4;\n const lineOffset = 2;\n\n const screenHeight = 64;\n const screenWidth = 64;\n\n /**\n * Gets the text line height\n */\n export function lineHeight(): number {\n return 8\n }\n\n /**\n * Number of lines\n */\n export function lineCount(): number {\n return ((screenHeight - textOffset) / lineHeight()) >> 0\n }\n\n\n /**\n * Fill a rectangle with specific color\n * @param x x-coordinate in pixel of the upper left corner\n * @param y y-coordinate in pixel of the upper left corner\n * @param width width of the rectangle\n * @param height height of the rectangle\n * @param color filling color of the rectangle\n */\n //% group=\"More\" advanced=true\n //% help=screen/fillRect\n //% blockId=fill_rect_ssd1306 block=\"fill the rectangle at %x %y with %width %height in %color\"\n //% parts=\"ssd1306\"\n export function fillRect(x: number, y: number, width: number, height: number, color: PixelColor): void{\n\n }\n\n /**\n * Show text on the screen at a specific line.\n * @param text the text to print on the screen, eg: \"Hello world\"\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshowstring block=\"show string %text|at line %line\"\n //% weight=98 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-string\n export function showString(text: string, line: number) {\n // line indexing starts at 1.\n line = (line - 1) >> 0;\n const nlines = lineCount();\n if (line < 0 || line >= nlines) return; // out of screen\n \n const h = lineHeight();\n const y = textOffset + h * line;\n fillRect(0, y, screenWidth, h, PixelColor.Black); // clear background\n printString(text, PixelColor.White, 0, y)\n }\n\n /**\n * Shows a number on the screen\n * @param value the numeric value\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshownumber block=\"show number %name|at line %line\"\n //% weight=96 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-number\n //% line.min=1 line.max=10\n export function showNumber(value: number, line: number) {\n showString(\"\" + value, line);\n }\n\n /**\n * Shows a name, value pair on the screen\n * @param value the numeric value\n * @param line the line number to print the text at (starting at 1), eg: 1\n */\n //% blockId=displayshowvalue block=\"show value %name|: %text|at line %line\"\n //% weight=94 inlineInputMode=\"inline\" blockGap=8\n //% group=\"Screen\"\n //% help=display/show-value\n //% line.min=1 line.max=10\n export function showValue(name: string, value: number, line: number) {\n value = Math.round(value * 1000) / 1000;\n showString((name ? name + \": \" : \"\") + value, line);\n }\n\n /**\n * Clear the screen\n */\n //% blockId=displayclear block=\"clear display\"\n //% weight=90\n //% group=\"Screen\"\n //% help=display/clear\n export function clear() {\n fillScreen(PixelColor.Black)\n }\n\n}\n\n\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace oled {\n\n /**\n * @brief Initialized screen\n *\n */\n //% group=\"More\" advanced=true\n //% help=screen/ssd1306_init_screen\n //% blockId=ssd1306_init_screen block=\"Initialized screen on address %address, with width %width and height %height\"\n //% parts=\"ssd1306\" weight=95 address.defl=0x74 width.defl=128 height.defl=64 shim=oled::initScreen\n function initScreen(address?: AddressScreen, width?: uint16, height?: uint16): void;\n\n /**\n * @brief Print string on screen at the given position\n *\n * @param x pixel coordinate on X axis\n * @param y pixel coordinate on Y axis\n * @param str the string to print\n * @param color the color use to print on screen\n */\n //% group=\"More\" advanced=true\n //% help=screen/printString\n //% blockId=print_string_ssd1306 block=\"print %str on screen in %color at x: %x|y: %y\"\n //% parts=\"ssd1306\" shim=oled::printString\n function printString(str: string, color: PixelColor, x: uint8, y: uint8): void;\n\n /**\n * @brief Fill the screen with specific color\n *\n * @param color the color use to fill the screen\n */\n //% group=\"More\" advanced=true\n //% help=screen/fillScreen\n //% blockId=fill_screen_ssd1306 block=\"fill the screen in %color\"\n //% parts=\"ssd1306\" shim=oled::fillScreen\n function fillScreen(color: PixelColor): void;\n\n /**\n * @brief set the color of a specific pixel\n *\n * @param x the coordinate pixel on X axis\n * @param y the coordinate pixel on Y axis\n * @param color the color of the pixel\n */\n //% group=\"More\" advanced=true\n //% help=screen/setPixel\n //% blockId=set_pixel_ssd1306 block=\"set pixel at %x, %y to %color\"\n //% parts=\"ssd1306\" shim=oled::setPixel\n function setPixel(x: uint8, y: uint8, color: PixelColor): void;\n\n /**\n * @brief Define if the screen should be inverted\n *\n * @param invert if True the screen is inverted, otherwise False\n */\n //% group=\"More\" advanced=true\n //% help=screen/invertScreen\n //% blockId=invert_screen_ssd1306 block=\"invert the screen : %invert\"\n //% parts=\"ssd1306\" shim=oled::invertScreen\n function invertScreen(invert: boolean): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", @@ -855,7 +856,7 @@ }, "wifi": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum HttpMethod {\n //%\n GET = 0,\n //%\n POST = 1,\n //%\n PUT = 2,\n //%\n HEAD = 3,\n //%\n DELETE = 4,\n //%\n PATCH = 5,\n //%\n OPTIONS = 6,\n //%\n CONNECT = 7,\n //%\n TRACE = 8,\n }\ndeclare namespace wifi {\n}\n\n// Auto-generated. Do not edit. Really.\n", - "pxt.json": "{\n \"name\": \"wifi\",\n \"description\": \"Wifi support for the module ISM43362-M3G-L44\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"wifi.ts\",\n \"wifi.cpp\",\n \"target_wifi.h\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"wifi\",\n \"description\": \"Wifi support for the module ISM43362-M3G-L44\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"wifi.ts\",\n \"wifi.cpp\",\n \"target_wifi.h\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Support for additional wifi services.\n */\n //%weight=40 icon=\"\\uf1eb\"\ndeclare namespace wifi {\n\n /**\n * @brief Execute HTTP method.\n * @param method HTTP method, eg: HttpMethod.GET\n * @param host Host, eg: \"google.com\"\n * @param port Port, eg: 80\n * @param urlPath Path, eg: \"/search?q=something\"\n * @param headers Headers\n * @param body Body\n */\n //% blockId=wifi_execute_http_method blockHidden=1 shim=wifi::executeHttpMethod\n function executeHttpMethod(method: HttpMethod, host: string, port: int32, urlPath: string, headers: string, body: string, time: int32): void;\n\n /**\n * Used internally by the library.\n */\n //% shim=wifi::onReceivedData\n function onReceivedData(handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_wifi.h": "#include \"pxt.h\"\n#include \"ISM43362_M3G_L44_driver.h\"\n\nnamespace pxt {\nclass WWifi {\n private:\n CODAL_SPI *spi;\n\n public:\n IsmDrvClass wifi;\n uint8_t wifi_status = WL_IDLE_STATUS;\n\n WWifi()\n : spi(pxt::getSPI(LOOKUP_PIN(WIFI_ISM43362_MOSI), LOOKUP_PIN(WIFI_ISM43362_MISO), LOOKUP_PIN(WIFI_ISM43362_SCK))),\n wifi(spi, LOOKUP_PIN(WIFI_ISM43362_CS), LOOKUP_PIN(WIFI_ISM43362_COMMAND_DATA_READY), LOOKUP_PIN(WIFI_ISM43362_RESET),\n LOOKUP_PIN(WIFI_ISM43362_WAKE_UP)) {}\n};\n} // namespace pxt", "wifi.cpp": "#include \"pxt.h\"\n#include \"target_wifi.h\"\n\n#define DEVICE_ID_WIFI_ISM43362_DATA_READY 2510\n#define WIFI_ISM43362_EVT_DATA_READY 1\n\nenum class HttpMethod {\n //%\n GET,\n //%\n POST,\n //%\n PUT,\n //%\n HEAD,\n //%\n DELETE,\n //%\n PATCH,\n //%\n OPTIONS,\n //%\n CONNECT,\n //%\n TRACE\n};\n\nnamespace pxt {\nSINGLETON(WWifi);\n}\n\nuint8_t _sock;\n\n/**\n * Support for additional wifi services.\n */\n//%weight=40 icon=\"\\uf1eb\"\nnamespace wifi {\n\nint networksVisible() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n wifi.ES_WIFI_ListAccessPoints();\n return wifi.ES_WIFI_GetApNbr();\n}\n\nvoid attach(String ssid, String passphrase) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n uint8_t &wifi_status = getWWifi()->wifi_status;\n\n if (wifi.ES_WIFI_Connect(ssid->getUTF8Data(), passphrase->getUTF8Data(), ES_WIFI_SEC_WPA_WPA2) == ES_WIFI_STATUS_OK) {\n wifi_status = WL_CONNECTED;\n } else {\n wifi.ES_WIFI_Disconnect();\n wifi_status = WL_CONNECT_FAILED;\n }\n}\n\nbool isAttached() {\n uint8_t &wifi_status = getWWifi()->wifi_status;\n return wifi_status == WL_CONNECTED;\n}\n\nvoid detach() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n uint8_t &wifi_status = getWWifi()->wifi_status;\n if (wifi_status != WL_NO_SHIELD) {\n wifi.ES_WIFI_Disconnect();\n wifi_status = WL_DISCONNECTED;\n }\n}\n\n/**\n * @brief Start building up a packet to send to the remote host\n * @param ip : IP to which to send the packet\n * @param port : port to which to send the packet\n * @retval 1 if successful, 0 if there was a problem with the supplied IP address or port\n */\nint connect(IPAddress ip, uint16_t port) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n int8_t sock;\n if (_sock == NO_SOCKET_AVAIL) {\n sock = wifi.getFreeSocket(); // get next free socket\n if (sock != -1) {\n _sock = sock;\n }\n }\n if (_sock != NO_SOCKET_AVAIL) {\n // set connection parameter and start client\n wifi.ES_WIFI_SetConnectionParam(_sock, ES_WIFI_TCP_CONNECTION, port, ip);\n wifi.ES_WIFI_StartClientConnection(_sock);\n return 1;\n }\n return 0;\n}\n\n/**\n * @brief Start building up a packet to send to the remote host\n * @param host : host to which to send the packet\n * @param port : port to which to send the packet\n * @retval 1 if successful, 0 if there was a problem with the supplied IP address or port\n */\nint connect(String host, uint16_t port) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n IPAddress remote_addr; // IP address of the host\n\n wifi.ES_WIFI_DNS_LookUp(host->getUTF8Data(), &remote_addr);\n return connect(remote_addr, port);\n}\n\n/**\n * @brief Get socket state\n @param None\n * @retval socket state\n */\nuint8_t status() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n if (_sock == 255) {\n return SOCKET_FREE;\n } else {\n return wifi.getSocketState(_sock);\n }\n}\n\n/**\n * @brief Get connection state\n @param None\n * @retval Socket state, FREE or BUSY\n */\nuint8_t connected() {\n if (_sock == 255) {\n return 0;\n } else {\n return status();\n }\n}\n\n/**\n * @brief Close the client connection\n * @param None\n * @retval None\n */\nvoid stop() {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n if (_sock == NO_SOCKET_AVAIL) {\n return;\n }\n wifi.ES_WIFI_StopServerSingleConn(_sock);\n _sock = NO_SOCKET_AVAIL;\n}\n\n/**\n * @brief Read up to size bytes from the current packet and place them into buffer\n * @param buffer : Where to place read data\n * @param size : length of data to read\n * @retval Returns the number of bytes read, or 0 if none are available\n */\nint read(char *buf, size_t size) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n uint16_t receivedLength = 0; // number of data received\n\n wifi.ES_WIFI_ReceiveData(_sock, (uint8_t *)buf, size, &receivedLength, WIFI_TIMEOUT);\n if (receivedLength < size) {\n buf[receivedLength] = '\\0'; // string end\n }\n return receivedLength;\n}\n\n/**\n * @brief Write size bytes from buffer into the packet\n * @param buf : data to write\n * @param size : size of data to write\n * @retval size of write data\n */\nsize_t write(const char *buf, size_t size) {\n IsmDrvClass &wifi = getWWifi()->wifi;\n\n uint16_t sentLength = 0; // number of data really send\n uint8_t *temp = (uint8_t *)buf;\n\n wifi.ES_WIFI_SendResp(_sock, temp, size, &sentLength, WIFI_TIMEOUT);\n return sentLength;\n}\n\nString getHttpMethodString(HttpMethod method) {\n switch (method) {\n case HttpMethod::GET:\n return String(\"GET\");\n case HttpMethod::POST:\n return String(\"POST\");\n default:\n return String();\n }\n}\n\n/**\n * @brief Execute HTTP method.\n * @param method HTTP method, eg: HttpMethod.GET\n * @param host Host, eg: \"google.com\"\n * @param port Port, eg: 80\n * @param urlPath Path, eg: \"/search?q=something\"\n * @param headers Headers\n * @param body Body\n */\n//% blockId=wifi_execute_http_method blockHidden=1\nvoid executeHttpMethod(HttpMethod method, String host, int port, String urlPath, String headers, String body, int time) {\n String methodName = getHttpMethodString(method);\n\n if (connect(host, 80)) {\n write(methodName->getUTF8Data(), methodName->getUTF8Size());\n write(\" \", 1);\n write(host->getUTF8Data(), host->getUTF8Size());\n write(\" HTTP/1.1\\r\\n\", 11);\n\n write(\"Host: \", 6);\n write(host->getUTF8Data(), host->getUTF8Size());\n write(\"\\r\\n\", 2);\n\n write(\"Connection: Close\\r\\n\", 19);\n\n if (headers->getLength() > 0) {\n write(headers->getUTF8Data(), headers->getUTF8Size());\n }\n if (body->getLength() > 0) {\n write(\"\\r\\n\", 2);\n write(body->getUTF8Data(), body->getUTF8Size());\n }\n write(\"\\r\\n\", 2);\n }\n}\n\n/**\n * Used internally by the library.\n */\n//%\nvoid onReceivedData(Action handler) {\n registerWithDal(DEVICE_ID_WIFI_ISM43362_DATA_READY, WIFI_ISM43362_EVT_DATA_READY, handler);\n}\n\n} // namespace wifi", @@ -864,19 +865,19 @@ "magnetics": { "enums.d.ts": "", "ns.ts": "\n//% color=\"#B4009E\" weight=40 icon=\"\\uf076\"\nnamespace magnetics {\n}", - "pxt.json": "{\n \"name\": \"magnetics\",\n \"description\": \"Radio service for mesh networking\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"radioBLE.cpp\",\n \"target_radioBLE.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"magnetics\",\n \"description\": \"Radio service for mesh networking\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"radioBLE.cpp\",\n \"target_radioBLE.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"ns.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "radioBLE.cpp": "#include \"pxt.h\"\n#include \"target_radioBLE.h\"\n#include \"HCI_SPI.h\"\n#include \"BLERemoteDevice.h\"\n\n#include \n\n// CODAL_SPI spiBLE(*LOOKUP_PIN(BLE_SPI_MISO), *LOOKUP_PIN(BLE_SPI_MOSI), *LOOKUP_PIN(BLE_SPI_SCLK));\nCODAL_SPI spiBLE(*lookupPin(43), *lookupPin(44), *lookupPin(42));\nHCI_SPI *hci = new HCI_SPI(spiBLE, *lookupPin(61U), *lookupPin(70U), *lookupPin(8U));\n\nchar stringBuffer[32] = {0};\n\nnamespace pxt {\nSINGLETON(WRadioBLE);\n\nvoid WRadioBLE::configure() {\n if (isConfigured) {\n return;\n }\n\n ble = new BLEDevice_Component(12345, hci);\n ble->init();\n\n isConfigured = true;\n}\n\n} // namespace pxt\n\nnamespace magnetics {\nString get_safe_string(std::vector &data) {\n\n std::string result = \"\";\n\n for (auto c : data) {\n if (c >= 32 && c <= 126) {\n result += (char)c;\n }\n }\n\n return mkString(result.c_str(), result.size());\n}\n\n/**\n * Start the device to sending data (by default the sending is activated)\n *\n */\n//% blockId=ble_start_emitting block=\"Start Send mode\"\n//% help=magnetics/ble_start_emitting weight=95\nvoid startEmitting() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->startAdvertising();\n radio->isAdvertisingStarted = true;\n}\n\n/**\n * Stop the device to sending data\n *\n */\n//% blockId=ble_stop_emitting block=\"Stop Send mode\"\n//% help=magnetics/ble_stop_emitting weight=95\nvoid stopEmitting() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->stopAdvertising();\n radio->isAdvertisingStarted = false;\n}\n\n/**\n * Start the device to receiving data (by default the receiving is activated)\n *\n */\n//% blockId=ble_start_scanning block=\"Start Scan mode\"\n//% help=magnetics/ble_start_scanning weight=91\nvoid startScanning() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->startScanning();\n radio->isScanningStarted = true;\n}\n\n/**\n * Stop the device to receiving data\n *\n */\n//% blockId=ble_stop_scanning block=\"Stop Scan mode\"\n//% help=magnetics/ble_stop_scanning weight=91\nvoid stopScanning() {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->ble->stopScanning();\n radio->isScanningStarted = false;\n}\n\n/**\n * Set the BLE device local name\n *\n * @param name The name\n */\n//% blockId=ble_set_local_name block=\"BLE device name : %name\"\n//% help=magnetics/ble_set_local_name weight=90\nvoid setLocalName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->advData.setLocalName(name->getUTF8Data());\n radio->ble->setAdvertisingData(radio->advData);\n}\n\n/**\n * Send string data\n *\n */\n//% blockId=ble_set_string_data block=\"BLE send string %data\"\n//% help=magnetics/ble_set_string_data weight=71\nvoid setAdvertisingStringData(String data) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n radio->scanData.setUserData(data->getUTF8Data());\n radio->ble->setScanResponseData(radio->scanData);\n}\n\n/**\n * Send \"key:value\" data\n *\n */\n//% blockId=ble_set_keyvalue_data block=\"BLE send key %key: value %value\"\n//% help=magnetics/ble_set_keyvalue_data weight=70\nvoid setAdvertisingKeyValueData(String key, float value) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n int32_t intPart = (int32_t)value;\n int8_t fracPart = ((int32_t)value * 100) - (intPart * 100);\n int size = sprintf(stringBuffer, \"%s:%d.%d\", key->getUTF8Data(), intPart, fracPart);\n\n if (size < 0) {\n setAdvertisingStringData(mkString(\"ERROR. KEY/VALUE\", 16));\n } else {\n setAdvertisingStringData(mkString(stringBuffer, size));\n }\n}\n\n/**\n * Is there any data from a device with specific name ?\n *\n */\n//% blockId=ble_available_data_from_name block=\"is available BLE data from %name\"\n//% help=magnetics/ble_available_data_from_name weight=65\nbool availableDataFromName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n return radio->ble->availableScan(name->getUTF8Data()) > 0;\n}\n\n/**\n * Get the data from the device with a specific name (if there are multiple device with the same name, the first who emit will\n * be use)\n *\n */\n//% blockId=ble_receive_data_from_name block=\"BLE receive data from %name\"\n//% help=magnetics/ble_receive_data_from_name weight=65\nString readDataFromName(String name) {\n auto radio = getWRadioBLE();\n radio->configure();\n\n std::vector result = radio->ble->getScanResult(name->getUTF8Data());\n\n if (result.size() > 0) {\n auto firstDevice = result[0];\n auto servicesDatas = firstDevice.getAllServiceDatas();\n\n if (servicesDatas.size() > 0) {\n return get_safe_string(servicesDatas[0].data);\n }\n }\n return mkString(\"\", 0);\n}\n\n/**\n * Run some code when we receive new message from device\n */\n//% blockId=ble_on_new_message block=\"on new message from %name\"\n//% help=magnetics/ble_on_new_message weight=60\nvoid onNewMessageReceived(String name, Action handler) {}\n\n} // namespace magnetics\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace magnetics {\n\n /**\n * Start the device to sending data (by default the sending is activated)\n *\n */\n //% blockId=ble_start_emitting block=\"Start Send mode\"\n //% help=magnetics/ble_start_emitting weight=95 shim=magnetics::startEmitting\n function startEmitting(): void;\n\n /**\n * Stop the device to sending data\n *\n */\n //% blockId=ble_stop_emitting block=\"Stop Send mode\"\n //% help=magnetics/ble_stop_emitting weight=95 shim=magnetics::stopEmitting\n function stopEmitting(): void;\n\n /**\n * Start the device to receiving data (by default the receiving is activated)\n *\n */\n //% blockId=ble_start_scanning block=\"Start Scan mode\"\n //% help=magnetics/ble_start_scanning weight=91 shim=magnetics::startScanning\n function startScanning(): void;\n\n /**\n * Stop the device to receiving data\n *\n */\n //% blockId=ble_stop_scanning block=\"Stop Scan mode\"\n //% help=magnetics/ble_stop_scanning weight=91 shim=magnetics::stopScanning\n function stopScanning(): void;\n\n /**\n * Set the BLE device local name\n *\n * @param name The name\n */\n //% blockId=ble_set_local_name block=\"BLE device name : %name\"\n //% help=magnetics/ble_set_local_name weight=90 shim=magnetics::setLocalName\n function setLocalName(name: string): void;\n\n /**\n * Send string data\n *\n */\n //% blockId=ble_set_string_data block=\"BLE send string %data\"\n //% help=magnetics/ble_set_string_data weight=71 shim=magnetics::setAdvertisingStringData\n function setAdvertisingStringData(data: string): void;\n\n /**\n * Send \"key:value\" data\n *\n */\n //% blockId=ble_set_keyvalue_data block=\"BLE send key %key: value %value\"\n //% help=magnetics/ble_set_keyvalue_data weight=70 shim=magnetics::setAdvertisingKeyValueData\n function setAdvertisingKeyValueData(key: string, value: number): void;\n\n /**\n * Is there any data from a device with specific name ?\n *\n */\n //% blockId=ble_available_data_from_name block=\"is available BLE data from %name\"\n //% help=magnetics/ble_available_data_from_name weight=65 shim=magnetics::availableDataFromName\n function availableDataFromName(name: string): boolean;\n\n /**\n * Get the data from the device with a specific name (if there are multiple device with the same name, the first who emit will\n * be use)\n *\n */\n //% blockId=ble_receive_data_from_name block=\"BLE receive data from %name\"\n //% help=magnetics/ble_receive_data_from_name weight=65 shim=magnetics::readDataFromName\n function readDataFromName(name: string): string;\n\n /**\n * Run some code when we receive new message from device\n */\n //% blockId=ble_on_new_message block=\"on new message from %name\"\n //% help=magnetics/ble_on_new_message weight=60 shim=magnetics::onNewMessageReceived\n function onNewMessageReceived(name: string, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_radioBLE.h": "#pragma once\n\n#include \"pxt.h\"\n\n#include \"BLEDevice_Component.h\"\n#include \"AdvertisingData.h\"\n#include \"AdvertisingFlagsBuilder.h\"\n\nnamespace pxt {\nclass WRadioBLE {\n private:\n public:\n codal::BLEDevice_Component *ble;\n AdvertisingData advData;\n AdvertisingData scanData;\n bool isAdvertisingStarted;\n bool isScanningStarted;\n\n WRadioBLE() : ble(nullptr), isAdvertisingStarted(false), isScanningStarted(false), isConfigured(false) {\n advData.setFlags(AdvertisingFlagsBuilder().addBrEdrNotSupported().addLeGeneralDiscoverableMode().build());\n }\n\n void configure();\n\n private:\n bool isConfigured;\n};\n} // namespace pxt\n" }, "datalogger": { "datalogger.ts": "/**\n * A tiny data logging framework\n */\n//% weight=80 color=#00a0a0 icon=\"\" blockGap=8\n//% groups='[\"Data\", \"Configuration\"]'\nnamespace datalogger {\n\n let separator = ',';\n let _headers: string[] = undefined;\n let _headersWritten: boolean = false;\n let _row: number[] = undefined;\n let _samples: number[] = undefined;\n let _start: number;\n let _enabled = true;\n let _samplingInterval = -1;\n let _lastSampleTime = -1;\n let _console = false;\n\n function clear() {\n _headers = undefined;\n _row = undefined;\n }\n\n function sendHeaders(){\n const line = _headers.join(separator);\n Serial.writeLine(`sep=${separator}`);\n Serial.writeLine(line);\n }\n\n function sendRow(){\n const line = _row.join(separator);\n Serial.writeLine(line);\n }\n\n function initRow() {\n if (_row) return;\n\n if (!_headers) {\n _headers = [];\n _headersWritten = false;\n _start = control.millis();\n }\n _row = [];\n _samples = [];\n _lastSampleTime = control.millis();\n const s = (_lastSampleTime - _start) / 1000;\n addValue(\"time\", s);\n }\n\n function commitRow() {\n // write row if any data\n if (_row && _row.length > 0) {\n \n // write headers for the first row\n if (!_headersWritten) {\n sendHeaders();\n if (_console){\n console.log(_headers.slice(1).join(separator));\n }\n _headersWritten = true;\n }\n\n // commit row data\n if (_samplingInterval <= 0 || control.millis() - _lastSampleTime >= _samplingInterval) {\n\n // average data\n for(let i = 1; i < _row.length; ++i) {\n _row[i] /= _samples[i];\n }\n\n // append row\n sendRow();\n\n if (_console) {\n // drop time\n console.log(_row.slice(1).join(separator));\n }\n\n // clear values\n _row = undefined;\n _lastSampleTime = -1;\n }\n }\n }\n\n /**\n * Start a new row of data\n */\n //% group=\"Data\"\n //% weight=100\n //% blockId=datalogAddRow block=\"data logger add row\"\n //% help=datalogger/add-row\n export function addRow(): void {\n if (!_enabled) return;\n\n commitRow();\n initRow();\n }\n\n /**\n * Add a named value to the row of data\n * @param name name of the cell, eg: \"x\"\n * @param value value of the cell, eg: 0\n */\n //% group=\"Data\"\n //% weight=99\n //% blockId=datalogAddValue block=\"data logger add %name|=%value\"\n //% blockGap=12\n //% help=datalogger/add-value\n export function addValue(name: string, value: number) {\n if (!_row) return;\n\n let idx = -1;\n\n // happy path\n if (_headers[_row.length] === name)\n idx = _row.length;\n else {\n idx = _headers.indexOf(name);\n if (idx < 0) {\n _headers.push(name);\n idx = _headers.length - 1;\n }\n }\n\n if( _row[idx] == undefined ){\n _row[idx] = value;\n _samples[idx] = 1;\n }\n else{\n _row[idx] += value;\n _samples[idx] += 1;\n }\n }\n\n /**\n * Commits any buffered row to disk\n */\n //%\n export function flush() {\n }\n\n /**\n * Set the minimum number of milliseconds between rows\n * @param millis milliseconds between each sample, eg: 50\n */\n //% group=\"Configuration\"\n //% blockId=datalogSetSamplingInterval block=\"set data logger sampling interval to $millis|(ms)\"\n //% millis.shadow=timePicker\n //% help=datalogger/set-sample-interval\n export function setSampleInterval(millis: number) {\n _samplingInterval = millis >> 0;\n }\n\n /**\n * Turn on or off datalogging\n * @param enabled \n */\n //% group=\"Configuration\"\n //% blockId=datalogEnabled block=\"data logger $enabled\"\n //% enabled.shadow=toggleOnOff\n //% help=datalogger/set-enabled\n export function setEnabled(enabled: boolean) {\n flush();\n _enabled = enabled;\n }\n\n /**\n * Send the data logger output to the console\n * @param enabled \n */\n //% group=\"Configuration\"\n //% blockId=\"datalogConsole\" block=\"data logger to console $enabled\"\n //% enabled.shadow=toggleOnOff\n //% help=datalogger/send-to-console\n export function sendToConsole(enabled: boolean) {\n _console = enabled;\n }\n}\n", - "pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Tiny data serial logging framework\",\n \"dependencies\": {\n \"core\": \"*\",\n \"serial\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n" + "pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Tiny data serial logging framework\",\n \"dependencies\": {\n \"core\": \"*\",\n \"serial\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n" }, "hcsr04": { "enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum MHCSR04Unit {\n //% block=\"m\"\n M = 0,\n //% block=\"dm\"\n Dm = 1,\n //% block=\"cm\"\n Cm = 2,\n //% block=\"mm\"\n Mm = 3,\n }\n\n\n declare const enum MDistanceBehold {\n //% block=\"Near\"\n Near = 0,\n //% block=\"Far\"\n Far = 1,\n }\ndeclare namespace HCSR04 {\n}\n\n// Auto-generated. Do not edit. Really.\n", "hcsr04.cpp": "#include \"pxt.h\"\n#include \"target_hcsr04.h\"\n\nenum class MHCSR04Unit {\n //% block=\"m\"\n M = 0, \n //% block=\"dm\"\n Dm = 1, \n //% block=\"cm\"\n Cm = 2, \n //% block=\"mm\"\n Mm = 3\n};\n\nenum class MDistanceBehold {\n //% block=\"Near\"\n Near = 0, \n //% block=\"Far\"\n Far = 1\n};\n\n\nnamespace pxt {\n SINGLETON(WHCSR04);\n}\n\n//% color=\"#456F93\" icon=\"\\uf028\" blockGap=8\nnamespace HCSR04 {\n \n/**\n * @brief Get the value of the sensor \n *\n * @param unit the unit of the distance\n * @return uint16_t\n */\n//% block=\"get distance in %unit\"\n//% blockId=\"hcsr04_get_distance\"\n//% group=\"HCSR04\" weight=76\n//% parts=\"hcsr04\"\nuint16_t getDistance(MHCSR04Unit unit) {\n return getWHCSR04()->hcsr04->getDistance(static_cast(unit));\n}\n\nvoid callActionNear() {\n runInParallel(getWHCSR04()->actNear);\n}\n\nvoid callActionFar() {\n runInParallel(getWHCSR04()->actFar);\n}\n\n/**\n * @brief Creates a new event that triggers when the sensor is near or far of the distance\n *\n * @param fromDistanceIs the direction that triggers the event\n * @param distance the value \n * @param unit the unit of the distance\n * @param handler what the event does\n */\n//% block=\"on distance %fromDistanceIs from %distance %unit\"\n//% blockId=\"hcsr04_register_distance_event\"\n//% group=\"HCSR04\" weight=67\n//% parts=\"hcsr04\"\nvoid onDistanceFrom(MDistanceBehold fromDistanceIs, uint16_t distance, MHCSR04Unit unit, Action handler) {\n switch (fromDistanceIs)\n {\n case MDistanceBehold::Near : \n getWHCSR04()->actNear = handler;\n getWHCSR04()->hcsr04->registerDistanceEvent(static_cast(fromDistanceIs), distance, static_cast(unit), callActionNear);\n break;\n case MDistanceBehold::Far : \n getWHCSR04()->actFar = handler;\n getWHCSR04()->hcsr04->registerDistanceEvent(static_cast(fromDistanceIs), distance, static_cast(unit), callActionFar);\n break;\n default:\n break;\n }\n}\n \n} // namespace HCSR04\n", - "pxt.json": "{\n \"name\": \"hcsr04\",\n \"description\": \"Library for the HC-SR04 sensor\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hcsr04.cpp\",\n \"target_hcsr04.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"hcsr04\",\n \"description\": \"Library for the HC-SR04 sensor\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"hcsr04.cpp\",\n \"target_hcsr04.h\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"pxtparts.json\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"hcsr04\": {\n \"simulationBehavior\": \"hcsr04\",\n \"visual\": {\n \"builtIn\": \"hcsr04\",\n \"width\": 250,\n \"height\": 116.3769,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 110,\n \"y\": 10\n },\n {\n \"x\": 121,\n \"y\": 10\n },\n {\n \"x\": 132,\n \"y\": 10\n },\n {\n \"x\": 143,\n \"y\": 10\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"fiveVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"D6\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"D7\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"assembly\": [\n {\n \"pinIndices\": [0, 1, 2, 3]\n }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% color=\"#456F93\" icon=\"\\uf028\" blockGap=8\ndeclare namespace HCSR04 {\n\n /**\n * @brief Get the value of the sensor \n *\n * @param unit the unit of the distance\n * @return uint16_t\n */\n //% block=\"get distance in %unit\"\n //% blockId=\"hcsr04_get_distance\"\n //% group=\"HCSR04\" weight=76\n //% parts=\"hcsr04\" shim=HCSR04::getDistance\n function getDistance(unit: MHCSR04Unit): uint16;\n\n /**\n * @brief Creates a new event that triggers when the sensor is near or far of the distance\n *\n * @param fromDistanceIs the direction that triggers the event\n * @param distance the value \n * @param unit the unit of the distance\n * @param handler what the event does\n */\n //% block=\"on distance %fromDistanceIs from %distance %unit\"\n //% blockId=\"hcsr04_register_distance_event\"\n //% group=\"HCSR04\" weight=67\n //% parts=\"hcsr04\" shim=HCSR04::onDistanceFrom\n function onDistanceFrom(fromDistanceIs: MDistanceBehold, distance: uint16, unit: MHCSR04Unit, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_hcsr04.h": "#include \"HCSR04Sensor.h\"\n#include \"pxt.h\"\n\nnamespace pxt {\nclass WHCSR04 {\n public:\n codal::HCSR04Sensor *hcsr04;\n Action actNear;\n Action actFar;\n\n WHCSR04() { \n hcsr04 = new codal::HCSR04Sensor(*LOOKUP_PIN(D6), *LOOKUP_PIN(D7), 1337);\n }\n};\n} // namespace pxt\n" @@ -885,7 +886,7 @@ "README.md": "# lcd\n\nPorted from STM32 lcd Support.\n", "lcd_i2c.cpp": "#include \"pxt.h\"\n#include \"target_lcd_i2c.h\"\n\nnamespace pxt {\nSINGLETON(WLCDI2C);\n}\n\nnamespace lcd_i2c {\nuint8_t strAddressToNumber(String addr) {\n uint8_t result = 0;\n\n for (uint8_t i = 0; i < 2 && i < addr->getLength(); i++) {\n char c = *(addr->getUTF8DataAt(i));\n\n if (c >= '0' && c <= '9') {\n result += c - '0';\n } else if (c >= 'A' && c <= 'F') {\n result += 10 + (c - 'A');\n } else if (c >= 'a' && c <= 'f') {\n result += 10 + (c - 'a');\n } else {\n return 0;\n }\n }\n\n return result;\n}\n\n/**\n * @brief Initialise the 16x2 screen with address 0x4E\n */\n//% blockId=\"I2C_LCD_INIT\"\n//% block=\"init i2c LCD\"\n//% weight=100\n//% blockGap=8\n//% parts=lcd_i2c\nvoid initScreen() {\n if (getWLCDI2C()->lcd != nullptr) {\n delete getWLCDI2C()->lcd;\n }\n\n getWLCDI2C()->lcd = new codal::I2C_LCD(getWLCDI2C()->i2c, 0x4E, 16, 2);\n getWLCDI2C()->lcd->init();\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * @brief Initialise the 16x2 screen with specific address\n *\n * @param address the hexadecimal address of the screen, eg: \"4E\"\n */\n//% blockId=\"I2C_LCD_INIT_ADDRESS\"\n//% block=\"init i2c LCD 0x%address\"\n//% weight=99\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid initScreenAddress(String address) {\n if (getWLCDI2C()->lcd != nullptr) {\n delete getWLCDI2C()->lcd;\n }\n\n getWLCDI2C()->lcd = new codal::I2C_LCD(getWLCDI2C()->i2c, strAddressToNumber(address), 16, 2);\n getWLCDI2C()->lcd->init();\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"I2C_LCD_SET_CURSOR\"\n//% block=\"set cursor position |at x %x|y %y\"\n//% weight=89\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid setCursor(uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n//% blockId=\"I2C_LCD_SHOW_NUMBER\"\n//% block=\"show number %n\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowNumber(int n) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n//% blockId=\"I2C_LCD_SHOW_STRING\"\n//% block=\"show string %s\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowString(String s) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(s->getUTF8Data());\n}\n\n/**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_VALUE\"\n//% block=\"show value %name = %value\"\n//% weight=90\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid ShowValue(String name, int value) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->print(name->getUTF8Data());\n getWLCDI2C()->lcd->print(':');\n getWLCDI2C()->lcd->print(value);\n}\n\n/**\n * Clear all display content\n */\n//% blockId=\"I2C_LCD_CLEAR\"\n//% block=\"clear screen\"\n//% weight=85\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid clear() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->clear();\n}\n\n/**\n * Turn on lcd backlight\n */\n//% blockId=\"I2C_LCD_BACKLIGHT_ON\"\n//% block=\"turn on backlight\"\n//% group=\"Backlight\"\n//% weight=71\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid BacklightOn() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->backlightOn();\n}\n\n/**\n * Turn off lcd backlight\n */\n//% blockId=\"I2C_LCD_BACKLIGHT_OFF\"\n//% block=\"turn off backlight\"\n//% group=\"Backlight\"\n//% weight=70\n//% blockGap=8\n//% parts=lcd_i2c trackArgs=0\nvoid BacklightOff() {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->backlightOff();\n}\n\n/**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_NUMBER_AT_POS\"\n//% block=\"show number %n|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid ShowNumberAtPos(int n, uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n ShowNumber(n);\n}\n\n/**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n//% blockId=\"I2C_LCD_SHOW_STRING_AT_POS\"\n//% block=\"show string %s|at x %x|y %y\"\n//% group=\"More\"\n//% weight=10\n//% blockGap=8\n//% x.min=0 x.max=15\n//% y.min=0 y.max=1\n//% parts=lcd_i2c trackArgs=0\nvoid ShowStringAtPos(String s, uint8_t x, uint8_t y) {\n if (getWLCDI2C()->lcd == nullptr)\n return;\n\n getWLCDI2C()->lcd->setCursor(x, y);\n ShowString(s);\n}\n} // namespace lcd_i2c", "ns.ts": "/**\n * Character lcd support\n */\n//% icon=\"\\uf0ae\" color=\"#219E42\" blockGap=8\n//% groups='[\"Display\", \"Configuration\"]'\n//% block=\"LCD I2C\"\nnamespace lcd_i2c {\n\n}", - "pxt.json": "{\n \"name\": \"lcd_i2c\",\n \"description\": \"Support for I2C Characeter LCD display (not grove one)\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd_i2c.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd_i2c.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.31\",\n \"pxt\": \"7.4.12\"\n }\n}\n", + "pxt.json": "{\n \"name\": \"lcd_i2c\",\n \"description\": \"Support for I2C Characeter LCD display (not grove one)\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"lcd_i2c.cpp\",\n \"pxtparts.json\",\n \"shims.d.ts\",\n \"target_lcd_i2c.h\",\n \"ns.ts\"\n ],\n \"public\": \"true\",\n \"targetVersions\": {\n \"target\": \"1.0.32\",\n \"pxt\": \"7.4.12\"\n }\n}\n", "pxtparts.json": "{\n \"lcd_i2c\": {\n \"simulationBehavior\": \"lcd_i2c\",\n \"visual\": {\n \"builtIn\": \"lcd_i2c\",\n \"width\": 322.7900085449219,\n \"height\": 147.52467,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 15,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 30,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 45,\n \"y\": 8.037069860858837\n },\n {\n \"x\": 60,\n \"y\": 8.037069860858837\n }\n ]\n },\n \"numberOfPins\": 4,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SDA\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"SCL\",\n \"style\": \"croc\",\n \"orientation\": \"-Z\"\n }\n ],\n \"assembly\": [\n { \"part\": true },\n { \"pinIndices\": [0] },\n { \"pinIndices\": [1] },\n { \"pinIndices\": [2, 3] }\n ]\n }\n}\n", "shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace lcd_i2c {\n\n /**\n * @brief Initialise the 16x2 screen with address 0x4E\n */\n //% blockId=\"I2C_LCD_INIT\"\n //% block=\"init i2c LCD\"\n //% weight=100\n //% blockGap=8\n //% parts=lcd_i2c shim=lcd_i2c::initScreen\n function initScreen(): void;\n\n /**\n * @brief Initialise the 16x2 screen with specific address\n *\n * @param address the hexadecimal address of the screen, eg: \"4E\"\n */\n //% blockId=\"I2C_LCD_INIT_ADDRESS\"\n //% block=\"init i2c LCD 0x%address\"\n //% weight=99\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::initScreenAddress\n function initScreenAddress(address: string): void;\n\n /**\n * Set cursor position at given position\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"I2C_LCD_SET_CURSOR\"\n //% block=\"set cursor position |at x %x|y %y\"\n //% weight=89\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::setCursor\n function setCursor(x: uint8, y: uint8): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n */\n //% blockId=\"I2C_LCD_SHOW_NUMBER\"\n //% block=\"show number %n\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowNumber\n function ShowNumber(n: int32): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n */\n //% blockId=\"I2C_LCD_SHOW_STRING\"\n //% block=\"show string %s\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowString\n function ShowString(s: string): void;\n\n /**\n * Show a name:value pair in lcd at given position\n * @param name : a string that is the name part of the name:value pair, eg: \"x\"\n * @param value : a number that is the value part of the name:value pair, eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_VALUE\"\n //% block=\"show value %name = %value\"\n //% weight=90\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowValue\n function ShowValue(name: string, value: int32): void;\n\n /**\n * Clear all display content\n */\n //% blockId=\"I2C_LCD_CLEAR\"\n //% block=\"clear screen\"\n //% weight=85\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::clear\n function clear(): void;\n\n /**\n * Turn on lcd backlight\n */\n //% blockId=\"I2C_LCD_BACKLIGHT_ON\"\n //% block=\"turn on backlight\"\n //% group=\"Backlight\"\n //% weight=71\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::BacklightOn\n function BacklightOn(): void;\n\n /**\n * Turn off lcd backlight\n */\n //% blockId=\"I2C_LCD_BACKLIGHT_OFF\"\n //% block=\"turn off backlight\"\n //% group=\"Backlight\"\n //% weight=70\n //% blockGap=8\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::BacklightOff\n function BacklightOff(): void;\n\n /**\n * Show a number in lcd at given position\n * @param n is number will be show, eg: 10, 100, 200\n * @param x is lcd column position, eg: 0\n * @param y is lcd row position, eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_NUMBER_AT_POS\"\n //% block=\"show number %n|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowNumberAtPos\n function ShowNumberAtPos(n: int32, x: uint8, y: uint8): void;\n\n /**\n * Show a string in lcd at given position\n * @param s is string will be show, eg: \"Hello\"\n * @param x is lcd column position, [0 - 15], eg: 0\n * @param y is lcd row position, [0 - 1], eg: 0\n */\n //% blockId=\"I2C_LCD_SHOW_STRING_AT_POS\"\n //% block=\"show string %s|at x %x|y %y\"\n //% group=\"More\"\n //% weight=10\n //% blockGap=8\n //% x.min=0 x.max=15\n //% y.min=0 y.max=1\n //% parts=lcd_i2c trackArgs=0 shim=lcd_i2c::ShowStringAtPos\n function ShowStringAtPos(s: string, x: uint8, y: uint8): void;\n}\n\n// Auto-generated. Do not edit. Really.\n", "target_lcd_i2c.h": "#include \"pxt.h\"\n#include \"STM32I2C.h\"\n#include \"i2c_lcd.h\"\n\nnamespace pxt {\nclass WLCDI2C {\n public:\n codal::STM32I2C i2c;\n codal::I2C_LCD *lcd;\n WLCDI2C() : i2c(*LOOKUP_PIN(SDA), *LOOKUP_PIN(SCL)), lcd(nullptr) {}\n};\n} // namespace pxt" diff --git a/targetlight.json b/targetlight.json index 29a6aab..8a50a1c 100644 --- a/targetlight.json +++ b/targetlight.json @@ -132,9 +132,10 @@ "ignoreDocsErrors": true, "uploadDocs": true, "versions": { - "branch": "main", - "commits": "https://github.com/letssteam/pxt-lets-steam/commits/f27999bbfa3f7b9efec725065f3f4048147033c9", - "target": "1.0.31", + "branch": "v1.0.32", + "tag": "v1.0.32", + "commits": "https://github.com/letssteam/pxt-lets-steam/commits/ca67d4a99b3f90769325fe37ffb2458c3b894b50", + "target": "1.0.32", "pxt": "7.4.12" }, "blocksprj": {