Syscalls and Memory-mapped I/O ports on CX: Difference between pages

From Hackspire
(Difference between pages)
Jump to navigation Jump to search
 
(Add 90040000)
 
Line 1: Line 1:
Syscalls are OS functions exposed by Ndless to C and assembly programs. This article describes the syscalls currently available with Ndless 3.1. You don't need to include the .h files in your program, only Ndless's standard ''os.h'' is required.
==00000000 - Boot1 ROM==
128kB of on-chip ROM.


Your help is needed to make this list grow to a full-fledged library. Try to find new syscalls, [[Ndless features and limitations#Syscalls|test them]] and share them for integration in Ndless.
==10000000 - SDRAM==


Functions marked with (*) are available only if the program is linked against [http://sourceware.org/newlib/ Newlib], i.e. when the <tt>nspire-ld</tt> switch <tt>-nostdlib</tt> is ''not'' used.
32 MiB SDRAM on CM or 64 MiB on CX. Managed by 0x8FFF0000.


Functions <s>crossed-out</s> are deprecated and shouldn't be used anymore.
==8FFF0000 - SDRAM controller==


==[http://en.wikipedia.org/wiki/C_standard_library C standard library]==
A DMC-340 r1p0.
===[http://www.cplusplus.com/reference/clibrary/cctype ctype.h]===
*[http://www.cplusplus.com/reference/clibrary/cctype/isalnum isalnum]
*[http://www.cplusplus.com/reference/clibrary/cctype/isalpha isalpha]
*[http://www.cplusplus.com/reference/clibrary/cctype/iscntrl iscntrl]
*[http://www.cplusplus.com/reference/clibrary/cctype/isdigit isdigit]
*[http://www.cplusplus.com/reference/clibrary/cctype/islower islower]
*[http://www.cplusplus.com/reference/clibrary/cctype/isprint isprint]
*[http://www.cplusplus.com/reference/clibrary/cctype/isspace isspace]
*[http://www.cplusplus.com/reference/clibrary/cctype/isupper isupper]
*[http://www.cplusplus.com/reference/clibrary/cctype/isxdigit isxdigit]
*[http://www.cplusplus.com/reference/clibrary/cctype/tolower tolower]
*[http://www.cplusplus.com/reference/clibrary/cctype/toupper/ toupper]


===[http://www.cplusplus.com/reference/clibrary/cerrno/ errno.h]===
==8FFF1000 - NAND controller==
*[http://www.cplusplus.com/reference/clibrary/cerrno/errno/ errno]


===[http://www.cplusplus.com/reference/clibrary/cstdarg/ stdarg.h]===
A PL351 r1p2.
*[http://www.cplusplus.com/reference/clibrary/cstdarg/va_list/ va_list]
*[http://www.cplusplus.com/reference/clibrary/cstdarg/va_start/ va_start]
*[http://www.cplusplus.com/reference/clibrary/cstdarg/va_arg/ va_arg]
*[http://www.cplusplus.com/reference/clibrary/cstdarg/va_end/ va_end]


===[http://www.cplusplus.com/reference/clibrary/cstdio/ stdio.h]===
==90000000 - General Purpose I/O (GPIO)==
*[http://www.cplusplus.com/reference/clibrary/cstdio/fclose/ fclose]
*[http://www.cplusplus.com/reference/clibrary/cstdio/feof/ feof]
*[http://www.cplusplus.com/reference/clibrary/cstdio/ferror/ ferror]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fflush/ fflush]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fgetc/ fgetc]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fgets/ fgets]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fopen/ fopen]
*[http://www.cplusplus.com/reference/clibrary/cstdio/freopen/ freopen]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/ fprintf]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fputs/ fputs]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fread/ fread]
*[http://www.cplusplus.com/reference/clibrary/cstdio/fseek/ fseek]
*[http://www.cplusplus.com/reference/clibrary/cstdio/ftell/ ftell] (since v3.1)
*[http://www.cplusplus.com/reference/clibrary/cstdio/fwrite/ fwrite]
*[http://www.cplusplus.com/reference/clibrary/cstdio/puts/ puts]
*[http://www.cplusplus.com/reference/clibrary/cstdio/printf/ printf]
*[http://www.cplusplus.com/reference/clibrary/cstdio/remove/ remove]
*[http://www.cplusplus.com/reference/clibrary/cstdio/rename/ rename]
*[http://www.cplusplus.com/reference/clibrary/cstdio/rewind/ rewind]
*[http://www.cplusplus.com/reference/clibrary/cstdio/stderr/ stderr]
*[http://www.cplusplus.com/reference/clibrary/cstdio/stdin/ stdin]
*[http://www.cplusplus.com/reference/clibrary/cstdio/stdout/ stdout]
*[http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/ sprintf]
*[http://www.cplusplus.com/reference/cstdio/sscanf/ sscanf] (since r874)
*[http://www.cplusplus.com/reference/clibrary/cstdio/ungetc/ ungetc]
*[http://www.cplusplus.com/reference/clibrary/cstdio/vsprintf/ vsprintf]


===[http://www.cplusplus.com/reference/clibrary/cstdlib/ stdlib.h]===
See [[GPIO Pins]]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/abort abort] (since v3.1)
*[http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/ atoi]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/atof/ atof]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/calloc/ calloc]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/exit/ exit] (*)
*[http://www.cplusplus.com/reference/clibrary/cstdlib/free/ free]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/ malloc]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/rand/ rand] (since v3.1 r610)
*[http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/ realloc]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/srand/ srand] (since v3.1 r610)
*[http://www.cplusplus.com/reference/clibrary/cstdlib/strtod/ strtod]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/strtol/ strtol]
*[http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/ strtoul]


===[http://www.cplusplus.com/reference/clibrary/cstring/ string.h]===
==90010000 - Fast timer==
*[http://www.cplusplus.com/reference/clibrary/cstring/memcpy/ memcpy]
*[http://www.cplusplus.com/reference/clibrary/cstring/memcmp/ memcmp]
*[http://www.cplusplus.com/reference/clibrary/cstring/memmove/ memmove]
*[http://forum.fukt.bsnet.se/cgi-bin/man/man2html?3+memrev memrev]
*[http://www.cplusplus.com/reference/clibrary/cstring/memset/ memset]
*[http://www.cplusplus.com/reference/clibrary/cstring/strcat/ strcat]
*[http://www.cplusplus.com/reference/clibrary/cstring/strcoll/ strcoll]
*[http://www.cplusplus.com/reference/clibrary/cstring/strchr/ strchr]
*[http://www.cplusplus.com/reference/clibrary/cstring/strcmp/ strcmp]
*[http://www.cplusplus.com/reference/clibrary/cstring/strcpy/ strcpy]
*[http://www.cplusplus.com/reference/clibrary/cstring/strcspn/ strcspn]
*[http://www.cplusplus.com/reference/clibrary/cstring/strerror/ strerror]
*[http://www.cplusplus.com/reference/clibrary/cstring/strlen/ strlen]
*[http://www.cplusplus.com/reference/clibrary/cstring/strncat/ strncat]
*[http://www.cplusplus.com/reference/clibrary/cstring/strncmp/ strncmp]
*[http://www.cplusplus.com/reference/clibrary/cstring/strncpy/ strncpy]
*[http://www.cplusplus.com/reference/clibrary/cstring/strpbrk/ strpbrk]
*[http://www.cplusplus.com/reference/clibrary/cstring/strrchr/ strrchr]
*[http://www.cplusplus.com/reference/clibrary/cstring/strspn/ strspn]
*[http://www.cplusplus.com/reference/clibrary/cstring/strstr/ strstr]
*[http://www.cplusplus.com/reference/clibrary/cstring/strtok/ strtok] (since v3.1)


==[http://en.wikipedia.org/wiki/C_POSIX_library C POSIX library]==
The same interface as 900C0000/900D0000, but runs at the speed of the APB clock (22.5MHz) rather than 32kHz. See [[#900D0000 - Second timer|Second timer]] for more info.
===[http://pubs.opengroup.org/onlinepubs/007908799/xsh/dirent.h.html dirent.h]===
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/opendir.html opendir] (since v3.1)
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir.html readdir] (since v3.1)
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/closedir.html closedir] (since v3.1)


===[http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/stat.h.html sys/stat.h]===
==90020000 - Serial UART==
*[http://www.opengroup.org/onlinepubs/000095399/functions/mkdir.html mkdir]
*[http://www.opengroup.org/onlinepubs/000095399/functions/stat.html stat]


===[http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html unistd.h]===
[http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf PL011].  
*[http://www.opengroup.org/onlinepubs/009695399/functions/chdir.html chdir]
*[http://pubs.opengroup.org/onlinepubs/009695399/functions/getcwd.html getcwd] (since r871)
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/rmdir.html rmdir]
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/unlink.html unlink]
*[http://pubs.opengroup.org/onlinepubs/007908799/xsh/ftruncate.html truncate] (since v3.1)


==[http://en.wikipedia.org/wiki/Nucleus_RTOS Nucleus]==
==90030000 - Unknown==
*<tt>int '''TCT_Local_Control_Interrupts'''(int mask)</tt>: sets the interrupt mask. Returns the previous mask.
*<tt>int '''NU_Current_Dir'''(const char *drive, char *path)</tt>: fills in <tt>path</tt> with the full path name of the current working directory. Use "A:" as ''drive''. Returns 0 on success.
*<tt>int '''NU_Get_First'''(struct dstat *statobj, const char * pattern)</tt>: given a pattern which contains both a path specifier and a search pattern, fills in the structure at <tt>statobj</tt> with information about the file and sets up internal parts of <tt>statobj</tt> to supply appropriate information for calls to <tt>NU_Get_Next</tt>. Returns non-zero if a match was not found.
*<tt>int '''NU_Get_Next'''(struct dstat *statobj)</tt>: given a pointer to a <tt>DSTAT</tt> structure that has been set up by a call to  <tt>NU_Get_First()</tt>, searches for the next match of the original pattern in the original path. Returns non-zero if found and updates <tt>statobj</tt> for subsequent calls to <tt>NU_Get_Next</tt>.
*<tt>void '''NU_Done'''(struct dstat *statobj)</tt>: given a pointer to a <tt>DSTAT</tt> structure that has been set up by a call to <tt>NU_Get_First()</tt>, frees internal elements used by the <tt>statobj</tt>.
*<tt>void '''NU_Set_Current_Dir'''(const char *name)</tt>: Set the current working directory on the default drive.


==TI-Nspire specific==
Probably some kind of hash/crypto thing.
===UTF-16 String API===
Since v3.1 r672.
*<tt>String</tt> : The type of the dynamic-length strings encoded in utf-16 format


===== Details =====
==90040000 - SPI controller==


  typedef struct {
A PL022 for communicating with the LCD panel controller, which is probably an ILI9341 or ILI9340.
    char * str;
Used on CX HW-W+ only.
    int len;
    int chunck_size;
    int unknown_field;
  } * String;


===== Init/Dispose functions =====
==90050000 - I2C controller==


*<tt>String '''string_new'''()</tt> : Returns a new String structure
The Touchpad on the CX is accessed through this controller. See [[Keypads#Touchpad I²C]] for protocol details. It seems to be a Synopsys Designware I2C adapter.
*<tt>void '''string_free'''(String)</tt> : Frees the String structure


===== Encoding functions =====
* 90050000 (R/W): Control register?
* 90050004 (?): ?
* 90050010 (R/W): Data/command register
* 90050014 (R/W): Speed divider for high period (standard speed) OS: 0x9c
* 90050018 (R/W): Speed divider for low period (standard speed) OS: 0xea
* 9005001c (R/W): Speed divider for high period (high speed) OS: 0x3b
* 90050020 (R/W): Speed divider for low period (high speed) OS: 0x2b
* 9005002c (R/W?): Interrupt status
* 90050030 (R/W): Interrupt mask
* 90050040 (R/W): Interrupt clear. Write 1 bits to clear
* 9005006c (R/W): Enable register
* 90050070 (R): Status register
* 90050074 (R?/W): TX FIFO?
* 90050078 (R?/W): RX FIFO?
* 900500f4 (?): ?
* 90050080 (?): ?


*<tt>char * '''string_to_ascii'''(String)</tt> : Returns String converted to ascii
==90060000 - Watchdog timer==
*<tt>int '''string_set_ascii'''(String, char *)</tt> : Erases the content of the String with the given ascii string
*<tt>int '''string_set_utf16'''(String, char *)</tt> : Erases the content of the String with the given utf16 string


===== String manipulation functions =====
Possibly an [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0270b/index.html ARM SP805] or compatible.


*<tt>void '''string_lower'''(String)</tt> : Lower all characters in the String
==90090000 - Real-Time Clock (RTC)==
*<tt>int '''string_concat_utf16'''(String, char *)</tt> : Concatenates to the String the given utf16 string
*<tt>void '''string_erase'''(String, int n)</tt> : Erases characters in the String from beginning to <tt>n</tt> (equivalent to substring(n, len))
*<tt>void '''string_truncate'''(String, int n)</tt> : Truncates the String to <tt>n</tt> chararacters (equivalent to substring(0, n))
*<tt>int '''string_insert_replace_utf16'''(String, char *, int start, int end)</tt> : Inserts the given utf16 string between <tt>start</tt> and <tt>end</tt> in the String by erasing its content. If <tt>end</tt> is -1 it erases the end of the String
*<tt>int '''string_insert_utf16'''(String, char *, int pos)</tt> : Inserts the given utf16 string at <tt>pos</tt> in the String.
*<tt>int '''string_sprintf_utf16'''(String, char *, ...)</tt> : Fills the String using the utf16 string format and arguments (equivalent to sprintf but with utf16 everywhere)  


===== Search functions =====
Similar to the [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0224b/index.html ARM PrimeCell PL031], but interrupt registers are different.


*<tt>char '''string_charAt'''(String, int pos)</tt> : Returns the character at <tt>pos</tt> in the String
* 90090000 (R): Current time, increments by 1 every second.
*<tt>int '''string_indexOf_utf16'''(String, int start, char *pattern)</tt> : Returns the index of <tt>pattern</tt> in the String starting at <tt>start</tt>. Returns -1 if not found
* 90090004 (R/W): Alarm value. When the time passes this, interrupt becomes active.
*<tt>int '''string_last_indexOf_utf16'''(String, int start, char *)</tt> : Returns the last index of <tt>pattern</tt> in the String starting at <tt>start</tt>. Returns -1 if not found
* 90090008 (R/W): Sets the value of 90090000 (clock will not read new time until a couple seconds later). Reads last value written.
*<tt>int '''string_compareTo_utf16'''(String, char *)</tt> : Returns 0 if the given utf16 string is equal to the String, -1 if it is superior, 1 if not
* 9009000C (R/W): Interrupt mask (1-bit)
*<tt>char * '''string_substring_utf16'''(String, char *pattern, int *ptr)</tt> : Returns the beginning of the String (in utf16) until <tt>pattern</tt> is met (excluded). <tt>ptr</tt> is modified so that it indicates the ending index of <tt>pattern</tt> or values -1 if the pattern doesn't exist. In such case the whole string is returned.
* 90090010 (R/W): Masked interrupt status, reads 1 if interrupt active and mask bit is set. Write 1 to acknowledge.
* 90090014 (R): Status
** Bit 0: Time setting in progress
** Bit 1: Alarm setting in progress
** Bit 2: Interrupt acknowledgment in progress
** Bit 3: Interrupt mask setting in progress


*<tt>char * '''string_substring'''(String dst, String src, int start, int end)</tt> : Writes in the <tt>dst</tt> the resulting substring from <tt>start</tt> to <tt>end</tt> (excluded) of <tt>src</tt>. Also returns the utf16 pointer
==900A0000 - Miscellaneous==


===== Other UTF-16 functions =====
* 900A0000 (R): ? 0x101
* 900A0004 (R/W): Set bit 0x20 to enable TI-84+ keypad link port. Other bits likely control functions of peripherals as well.
* 900A0008 (W): Write a 2 to cause a hardware reset
* 900A0010 (R/W): Fast timer interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
* 900A0014 (R/W): Fast timer interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0010] should trigger an IRQ.
* 900A0018 (R/W): Timer 1 interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
* 900A001C (R/W): Timer 1 interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0018] should trigger an IRQ.
* 900A0020 (R/W): Timer 2 interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
* 900A0024 (R/W): Timer 2 interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0020] should trigger an IRQ.
* 900A0028-900A002C (R): These registers together give a 64-bit number (28 is low, 2C is high) which comprises 56 data bits and 8 parity checking bits, allowing any single-bit error in it to be detected and corrected.
** Parity bit 0: Check of all data bits
** Parity bits 1, 2, 4, 8, 16, and 32: Checks of the data bits whose positions, expressed in binary, have that respective bit set.
** Data bits 3, 5-7, 9-15, 17-31, and 33-55: Serial number (middle part of the calculator's Product ID)
** Data bits 56-57: Unknown
** Data bits 58-62: "ASIC user flags"; must match the 80E0 field in an OS image. 01 = CAS, 00 = non-CAS, 03 = CM CAS, 02 = CM non-CAS.
** Parity bit 63: Check of parity bits 1, 2, 4, 8, 16, and 32.
* 900A0F04 (R/W): Unknown; Boot1 sets this to 0x1D


*<tt>void '''ascii2utf16'''(void *buf, const char *str, int max_size)</tt>: converts the ASCII string <tt>str</tt> to the UTF-8 string <tt>buf</tt> of size <tt>max_size</tt>.
==900B0000 - Power management==
*<tt>void '''utf162ascii'''(void *buf, const char *str, int max_size)</tt>: Since v3.1 r607. converts the UTF-16 string <tt>str</tt> to the ASCII string <tt>buf</tt> of size <tt>max_size</tt>.
*<tt>size_t '''utf16_strlen'''(const char * s)</tt>: Since v3.1 r607. Returns the length in characters of the UTF-16 string <tt>s</tt>.


===Graphic Context API===
* 900B0000 (R/W): [[Clock speed]] load value
* 900B0004 (R/W): 25-bit mask of which events may wake the hardware up from low-power mode.
** Bit 10: Unknown, probably the [[#90100000 - TI-84 Plus link port|TI-84 Plus link port]]
** Bit 12: [[#90090000 - Real-Time Clock (RTC)|RTC]] interrupt
** Bit 13: Unknown, probably ON key or USB activity
** Bit 17: Battery door open/close?
** Bit 23: Keypad remove/replace?
* 900B0008 (R/W): Reason for waking up from low-power mode. Write "1" bits to acknowledge.
* 900B000C (R/W): Clock speed control. Write 4 to set the clock speed according to the value in 900B0000. If interrupts are disabled the new clock speed will only become effective after exiting the program. Write 3A to enter low-power mode; this requires various peripherals to be prepared and probably works by stopping the clock.
* 900B0010 (R/W): ON interrupt mask (1-bit). 1 if ON interrupt should be serviced or 0 if not.
* 900B0014 (R/W): Bit 0 is set if ON interrupt is requested. Bit 1 also causes an interrupt, but the cause is unknown (and it is not masked by [900B0010]) - it is set after writing 4 to 900B000C. Write "1" bits to reset the requests.
* 900B0018 (R/W): Disable bus access to peripherals. Reads will just return the last word read from anywhere in the address range, and writes will be ignored.
** Bit 4: [[#C4000000 - Analog-to-Digital Converter (ADC)]]
** Bit 5: [[#B0000000 - USB OTG controller]]
** Bit 6: [[#B4000000 - USB HOST controller]]
** Bit 7: [[#B8010000 - SRAM Controller]]
** Bit 10: [[#CC000000 - SHA-256 hash generator]]
** Bit 11: [[#900C0000 - First timer]]
** Bit 12: [[#900D0000 - Second timer]]
** Bit 13: [[#90060000 - Watchdog timer]]
** Bit 17: [[#90020000 - Serial UART]]
** Bit 22: [[#90110000_-_LED]]?
* 900B0020 (R/W): ? - Possibly another peripheral bus access disable register.
* 900B0024 (R): Reads current clock speed value (see 900B0000 for details)
* 900B0028 (R): Bit 4 (0x10) clear when ON key pressed


----
==900C0000 - First timer==


Since v3.1 r898.
Configured as ~105 Hz timer by the OS (only used in the TI-84+ emulator). Same port structure as [[#900D0000 - Second timer|Second timer]].


The TI-Nspire Graphic Context (or "ngc") is an API created by TI, inspired by Java's Graphics2D and using Nucleus GRAFIX functions.
==900D0000 - Second timer==


This API is intensively used by the OS internally and is directly exposed in the [[Lua_Programming#GC_.28as_in_Graphics_Context.29|TI-Nspire Lua framework]].
Two timers are located here, but only the first can generate IRQs. IRQ status/mask is located at [900A0020]. Configured as a ~100 Hz timer by the OS.


In order to use this API inside your program, use this line:
Timer is a [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/Babehiha.html SP804].
#include <ngc.h>


The Ndless SDK provides an GC-based demo in <tt>_samples/ngc/</tt>.
==900E0000 - Keypad controller==


===== Global parameters =====
See also [[Keypads]] for information about the keypads themselves.


*<tt>Gc *'''gui_gc_global_GC_ptr'''</tt> is the graphic context used (and already allocated/setup) by the OS. In fact, <tt>gui_gc_new</tt> has been removed from the syscall list because it made the TI-Nspire Clickpad/Touchpad crash, preferring the use of this graphic context. Furthermore, the OS seems to use the same gc from the beginning of its initialization, why not Ndless then?.
* 900E0000 (R/W):
''Notice: It is recommended to save the value of <tt>gui_gc_global_GC_ptr</tt> in a local variable as such:
** Bits 0-1: Scan mode
Gc gc = *gui_gc_global_GC_ptr;
*** Mode 0: Idle.
*** Mode 1: Indiscriminate key detection. Data registers are not updated, but whenever any key is pressed, interrupt bit 2 is set (and cannot be cleared until the key is released).
*** Mode 2: Single scan. The keypad is scanned once, and then the mode returns to 0.
*** Mode 3: Continuous scan. When scanning completes, it just starts over again after a delay.
** Bits 2-15: Number of APB cycles to wait before scanning each row
** Bits 16-31: Number of APB cycles to wait between scans
* 900E0004 (R/W):
** Bits 0-7: Number of rows to read (later rows are not updated in 900E0010-900E002F, and just read as whatever they were before being disabled)
** Bits 8-15: Number of columns to read (later column bits in a row are set to 1 when it is updated)
* 900E0008 (R/W): Keypad interrupt status/acknowledge (3-bit). Write "1" bits to acknowledge.
** Bit 0: Keypad scan complete
** Bit 1: Keypad data register changed
** Bit 2: Key pressed in mode 1
* 900E000C (R/W): Keypad interrupt mask (3-bit). Set each bit to 1 if the corresponding event in [900E0008] should cause an interrupt.
* 900E0010-900E002F (R): Keypad data, one halfword per row.  
* 900E0030-900E003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown.
* 900E0040 (R/W): Interrupt enable. Bits unknown but seems to be related to touchpad. Causes interrupt on touchpad touched.
* 900E0044 (R/W): Interrupt status. Bits unknown. Write 1s to acknowledge.
* 900E0048 (R/W): Unknown


The <tt>gc</tt> is an off-screen buffer. Thus, each function that draws on this gc will not affect the screen until you use <tt>[[Syscalls#Blit_functions|gui_gc_blit_to_screen(gc)]]</tt>.
==900F0000 - HDQ/1-Wire and LCD contrast==


The OS tends to blit the screen if it has been updated using a timed Nucleus task. You can use this principle in your programs but nothing forces you to do so. Thus, you can freely blit the screen as many times as you want when running an animation and only refresh part of it using <tt>gui_gc_blit_to_screen_region(gc, x, y, w, h)</tt> when needed.
The HDQ/1-Wire registers resemble those on the TI OMAP processors, and are possibly used to communicate with the wireless cradle. There is no conceivable reason for the LCD contrast register to be part of the same module, but here it is. :-(


===== Init/Dispose functions=====
* 900F0004 (W): Transmitted data
* 900F0008 (R): Received data
* 900F000C (R/W): Control/status
* 900F0010 (R): Interrupt status (automatically acknowledged when read)
* 900F0020 (R/W): LCD contrast/backlight. Valid range for contrast: 0x11a to 0x1ce; normal value is 0x174. However, it can range from 0x100 (backlight off) to about 0x1d0 (about max brightness).


*<tt>Gc '''gui_gc_copy'''(Gc, int w, int h)</tt> - Allocates a new Gc from an existing one copying its parameters, replacing port's width & height with the given ones. '''Does not copy the screen buffer.'''
==90110000 - LED==
*<tt>int '''gui_gc_begin'''(Gc)</tt> - Initializes graphic port (seems to allocate 2 memory areas), may be used before any graphic manipulation.
''Notice: <tt>gui_gc_setRegion</tt> may be used before <tt>gui_gc_begin</tt> in order to make <tt>gui_gc_clipRect</tt> work with proper coordinates.''
*<tt>void '''gui_gc_finish'''(Gc)</tt> - Resets the graphic port parameters (seems to free 2 memory areas).
*<tt>void '''gui_gc_free'''(Gc)</tt> - Frees the given gc.


===== Set/Get Attributes functions=====
* 90110B00 (R/W): Control register
** Bit 0: Set this bit to enable green light blink data. If green blink data iteration is not on, the green light state is read from bit 0 of green blink data.
** Bit 1: Set this bit and bit 6 to enable green blink data iteration.
** Bit 2: Set this bit to force green light off. Overrides bit 4.
** Bit 3: Set this bit to force red light off. Overrides bits 5 and 13.
** Bit 4: Set this bit to force green light on.
** Bit 5: Set this bit to force red light on.
** Bit 6: See this bit and bit 1 to enable green blink data iteration. Reset before modifying green blink data or delay.
** Bit 9: Set this bit to enable red light blink data. If red blink data iteration is not on, the red light state is read from bit 0 of red blink data.
** Bit 10: Set this bit and bit 12 to enable red blink data iteration.
** Bit 12: Set this bit and bit 10 to enable red blink data iteration. Reset before modifying red blink data or delay.
** Bit 13: Forces red light on if bit 4 is 0, or red light off if bit 4 is 1. (?)
* 90110B04 (R/W): Green blink data. 32 bits of on and off state, represented by 1 and 0. Iteration is done from bit 31 to bit 0 repeatedly.
* 90110B08 (R/W): Green blink delay (negative). OS sets this to -2048.
* 90110B0C (R/W): Red blink data. 32 bits of on and off state, represented by 1 and 0. Iteration is done from bit 31 to bit 0 repeatedly.
* 90110B10 (R/W): Red blink delay (negative). OS sets this to -2048.


*<tt>void '''gui_gc_clipRect'''(Gc, int x, int y, int w, int h, gui_gc_ClipRectOp op)</tt> - Contrains the given <tt>gc</tt> to draw only in a certain area. If <tt>op</tt> is GC_CRO_RESET, the other parameters are ignored.
Note: If red and green lights are on at the same time, the color becomes yellow.
*<tt>void '''gui_gc_setColorRGB'''(Gc, int r, int g, int b)</tt> - Changes the pen color of the given <tt>gc</tt>
*<tt>void '''gui_gc_setColor'''(Gc, int color)</tt> - same as <tt>gui_gc_setColorRGB</tt> but using 0xRRGGBB color format
*<tt>void '''gui_gc_setAlpha'''(Gc, gui_gc_Alpha)</tt> - Changes the pen alpha mode of the given <tt>gc</tt> to non-transparent or semi-transparent.
*<tt>void '''gui_gc_setFont'''(Gc, gui_gc_Font)</tt> - Changes the font of the given <tt>gc</tt>
*<tt>gui_gc_Font '''gui_gc_getFont'''(Gc)</tt> - Returns the current font of the given <tt>gc</tt>
*<tt>void '''gui_gc_setPen'''(Gc, gui_gc_PenSize, gui_gc_PenMode)</tt> - Changes the pen size and mode of the given <tt>gc</tt>
*<tt>void '''gui_gc_setRegion'''(Gc, int xs, int ys, int ws, int hs, int x, int y, int w, int h)</tt> - Changes the region (or viewport) of the given <tt>gc</tt>. The region <x,y,w,h> is based on screen coordinates <xs,ys,ws,hs>. <tt>gui_gc_setRegion</tt> will offset all the drawings and coordinates you are using: It can be useful to use this function instead of creating a separate gc to draw an inner window.
''Notice: <tt>gui_gc_clipRect</tt> will work with old coordinates as long as you don't reset the region to the entire screen, for example, by using this main:''


int main(void)
==A4000000 - Internal SRAM==
{
  /* Get the gc */
  Gc gc = *gui_gc_global_GC_ptr;
  /* Initialization */
  gui_gc_setRegion(gc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
  gui_gc_begin(gc);
  /* Draw */
  gui_gc_clipRect(gc, 10, 10, 10, 10, GC_CRO_SET);
  gui_gc_fillRect(gc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); /* Will only draw a 10x10 rectangle */
  /* Blit & finish */
  gui_gc_blit_to_screen(gc);
  gui_gc_finish(gc);
  return 0;
}


===== Draw functions =====
0x20000 bytes SRAM, managed by the controller at 0xB8000000.


*<tt>void '''gui_gc_fillArc'''(Gc, int x, int y, int w, int h, int start, int end)</tt> - Fills an arc inside the box <<tt>x,y,w,h</tt>>. <tt>start</tt> and <tt>end</tt> have to be multiplied by 10.
==B0000000 - USB OTG controller==
/* Disk at <0,0> of size <20,20> */
gui_gc_fillArc(gc, 0, 0, 20, 20, 0, 3600);


*<tt>void '''gui_gc_fillPoly'''(Gc, int * points, int count)</tt> - Fills a polygon shape. <tt>points</tt> is a table of successive x,y coordinates.
The OTG controller on all models is a ChipIdea-based dual-role USB controller. It only supports full speed communications so the PFSC bit (bit 24) must be set in the PORTSC register when in host mode. Otherwise, it'll attempt to connect at high speed for devices that support it and will never succeed in enumerating them.
/* Filled rectangle shape at <100,100> of size <50,50> */
int points[] = {100,100, 150,100, 150,150, 100,150, 100,100};
gui_gc_fillPoly(gc, points, sizeof (points) / sizeof (points[0]));


*<tt>void '''gui_gc_fillRect'''(Gc, int x, int y, int w, int h)</tt> - Fills a rectangle.
Documentation can be found in the [http://www.freescale.com/files/dsp/doc/ref_manual/IMX23RM.pdf IMX233 reference manual].
/* Filled rectangle at <100,100> of size <50,50> */
The host interface is, again, based on EHCI; but the register defaults are different. The addresses have been adjusted from the ones contained in the IMX233 reference manual.
gui_gc_fillRect(gc, 100, 100, 50, 50);


*<tt>void '''gui_gc_fillGradient'''(Gc, int x, int y1, int w, int y2, int start_color, int end_color, int vertical)</tt> - Fills a line-based gradient from <tt>start_color</tt> to <tt>end_color</tt> (both in 0xRRGGBB format). As a side-effect, current color is changed to <tt>end_color</tt> after the call. ''May only work for certain color pairs'' (it may be cleverer to recreate this function rectangle-based by your own).
* Module identification registers
/* Black to White vertical gradient at <10,10> of size <50,50> */
** B0000000: HW_USBCTRL_ID - default 0xE241FA05
gui_gc_fillGradient(gc, 10, 10, 50, 50, 0x000000, 0xffffff, 1);
** B0000004: HW_USBCTRL_HWGENERAL - default 0x00000015
** B0000008: HW_USBCTRL_HWHOST - default 0x10020001
** B000000C: HW_USBCTRL_HWDEVICE - default 0x0000000B
** B0000010: HW_USBCTRL_HWTXBUF - default 0x40060910
** B0000014: HW_USBCTRL_HWRXBUF - default 0x00000710
* Capability registers
** B0000100: HW_USBCTRL_CAPLENGTH - default 0x01000040
** B0000104: HW_USBCTRL_HCSPARAMS - default 0x00010011
** B0000108: HW_USBCTRL_HCCPARAMS - default 0x00000006
** B0000120: HW_USBCTRL_DCIVERSION - default 0x00000001
** B0000124: HW_USBCTRL_DCCPARAMS - default 0x00000185 (host-capable, device-capable, 5 endpoints)
* Operational registers
** B0000140: HW_USBCTRL_USBCMD - default 0x00080B00 in host mode, 0x00080000 in device mode
** B0000144: HW_USBCTRL_USBSTS - default 0x00001000 in host mode, 0x00000000 in device mode
** B0000148: HW_USBCTRL_USBINTR - default 0x00000000
** B000014C: HW_USBCTRL_FRINDEX - default 0x00000000
** B0000154: (in host mode) HW_USBCTRL_PERIODICLISTBASE - default 0x00000000
** B0000154: (in device mode) HW_USBCTRL_DEVICEADDR - default 0x00000000
** B0000158: (in host mode) HW_USBCTRL_ASYNCLISTADDR - default 0x00000000
** B0000158: (in device mode) HW_USBCTRL_ENDPOINTLISTADDR - default 0x00000000
** B000015C: HW_USBCTRL_TTCTRL - default 0x00000000
** B0000160: HW_USBCTRL_BURSTSIZE - default 0x00001010
** B0000164: HW_USBCTRL_TXFILLTUNING - default 0x000000000
** B000016C: HW_USBCTRL_IC_USB - default 0x00000000
** B0000170: HW_USBCTRL_ULPI - default 0x00000000
** B0000178: HW_USBCTRL_ENDPTNAK - default 0x00000000
** B000017C: HW_USBCTRL_ENDPTNAKEN - default 0x00000000
** B0000184: HW_USBCTRL_PORTSC1 - default 0x10000000
** B00001A4: HW_USBCTRL_OTGSC - default 0x00000120
** B00001A8: HW_USBCTRL_USBMODE - default 0x00000000
** B00001AC: HW_USBCTRL_ENDPTSETUPSTAT - default 0x00000000
** B00001B0: HW_USBCTRL_ENDPTPRIME - default 0x00000000
** B00001B4: HW_USBCTRL_ENDPTFLUSH - default 0x00000000
** B00001B8: HW_USBCTRL_ENDPTSTAT - default 0x00000000
** B00001BC: HW_USBCTRL_ENDPTCOMPLETE - default 0x00000000
** B00001C0: HW_USBCTRL_ENDPTCTRL0 - default 0x00100010
** B00001C4: HW_USBCTRL_ENDPTCTRL1 - default 0x00000000
** B00001C8: HW_USBCTRL_ENDPTCTRL2 - default 0x00000000
** B00001CC: HW_USBCTRL_ENDPTCTRL3 - default 0x00000000
** B00001D0: HW_USBCTRL_ENDPTCTRL4 - default 0x00000000


*<tt>void '''gui_gc_drawArc'''(Gc, int x, int y, int w, int h, int start, int end)</tt> - Draws an arc insidethe box <<tt>x,y,w,h</tt>>. <tt>start</tt> and <tt>end</tt> have to be multiplied by 10.
===Role switching===
/* Circle at <0,0> of size <20,20> */
gui_gc_drawArc(gc, 0, 0, 20, 20, 0, 3600);


*<tt>void '''gui_gc_drawLine'''(Gc, int x1, int y1, int x2, int y2)</tt> - Draws a line from <<tt>x1,y1</tt>> to <<tt>x2,y2</tt>>.
During role switching some GPIO output registers are modified.
/* Line from <0,0> to <320,240> */
gui_gc_drawLine(gc, 0, 0, 320, 240);


*<tt>void '''gui_gc_drawRect'''(Gc, int x, int y, int w, int h)</tt> - Draws an empty rectangle at <<tt>x,y</tt>> of size <<tt>w,h</tt>>
* GPIO2:
/* Empty rectangle at <100,100> of size <50,50> */
** Active low.
gui_gc_fillRect(gc, 100, 100, 50, 50);
** Controls VBUS/pull-up (drives VBUS to 5v for host mode)


*<tt>void '''gui_gc_drawString'''(Gc, char * utf16, int x, int y, gui_gc_StringMode flags)</tt> - Draws an UTF-16 Null-terminated string at <<tt>x,y</tt>> using <tt>flags</tt>.
* USB-B: GPIO6
/* "Hello" where <50,50> is actually the top left of it */
** Active low.
gui_gc_drawString(gc, "H\0e\0l\0l\0o\0\0", 50, 50, GC_SM_TOP);
** Probably controls charging from USB


/* Upside-down "World" at <100,100> */
==B4000000 - USB HOST controller==
gui_gc_drawString(gc, "W\0o\0r\0l\0d\0\0", 100, 100, GC_SM_DOWN);


*<tt>void '''gui_gc_drawPoly'''(Gc, int * points, int count)</tt> - Draws a polygon shape. <tt>points</tt> is a table of successive x,y coordinates.
Same port structure as B0000000.
/* Empty rectangle shape at <100,100> of size <50,50> */
int points[] = {100,100, 150,100, 150,150, 100,150, 100,100};
gui_gc_fillPoly(gc, points, sizeof (points) / sizeof (points[0]));


*<tt>void '''gui_gc_drawIcon'''(Gc, int res, int icon, int x, int y)</tt> - Draws an icon pre-defined by the OS.
==B8001000 - SRAM Controller==
/* Draw a star at <100,100> */
gui_gc_drawIcon(gc, RES_SYST, 255, 100, 100);


*<tt>void '''gui_gc_drawSprite'''(Gc, gui_gc_Sprite *, int x, int y)</tt> - Draws a sprite at <<tt>x,y</tt>>. Sprite pixels color is affected by <tt>gui_gc_setColor[RGB]</tt>
A [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0380g/DDI0380G_smc_pl350_series_r2p1_trm.pdf PL352] r1p2.
/* Draw a hand-made gradient at <100, 100> */
gui_gc_Sprite s = {.width = 9, .height = 1};
s.pixels = (char *) {0x0, 0x22, 0x44, 0x66, 0x88, 0xAA, 0xCC, 0xEE, 0xFF};
gui_gc_drawSprite(gc, &s, 100, 100);


*<tt>void '''gui_gc_drawImage'''(Gc, char * TI_Image, int x, int y)</tt> - Draws an image in [[TI.Image]] format at <<tt>x,y</tt>>
==C0000000 - LCD controller==
/* Gray image at <100,100> of size <10,10> */
gui_gc_Image_header hdr = {.width = 10, .height = 10, .empty = 0, .depth = 2, .enc = 1};
hdr.buff_size = hdr.depth * hdr.width;
unsigned size = hdr.buff_size * hdr.height;
char * img = calloc(size + sizeof (gui_gc_Image_header), 1);
memcpy(img, &hdr, sizeof (gui_gc_Image_header));
memset(img + sizeof (gui_gc_Image_header), 77, size);
gui_gc_drawImage(gc, img, 100, 100);


===== Metric functions =====
A [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0293c/index.html PL111].


*<tt>int '''gui_gc_getStringWidth'''(Gc, gui_gc_Font, char * utf16, int start, int length)</tt> -
==C4000000 - Analog-to-Digital Converter (ADC)==
*<tt>int '''gui_gc_getCharWidth'''(Gc, gui_gc_Font, short utf16 char)</tt> -
*<tt>int '''gui_gc_getStringSmallHeight'''(Gc, gui_gc_Font, char * utf16, int start, int length)</tt> -
*<tt>int '''gui_gc_getCharHeight'''(Gc, gui_gc_Font, short utf16 char)</tt> -  
*<tt>int '''gui_gc_getStringHeight'''(Gc, gui_gc_Font, char * utf16, int start, int length)</tt> -  
*<tt>int '''gui_gc_getFontHeight'''(Gc, gui_gc_Font)</tt> -  
*<tt>int '''gui_gc_getIconSize'''(Gc, int ressource, int icon, int * w, int * h)</tt> -


===== Blit functions =====
Used to check various voltages. Channels 1 ("VBATT"), 2 ("VSYS"), and 4 ("B12") are used to check the battery status; channel 3 is used to determine which keypad is in use.


*<tt>void '''gui_gc_blit_to_screen'''(Gc gc)</tt> - Blits the screen using the given <tt>gc</tt>
* C4000000 (R): Masked interrupt status (4 bits per channel: bits 0-3 are for channel 0, etc)
*<tt>void '''gui_gc_blit_to_screen_region'''(Gc gc, int x, int y, int w, int h)</tt> - Blits part of the screen (region <<tt>x,y,w,h</tt>>) using the given <tt>gc</tt>
* C4000004 (R/W): Raw interrupt status, write 1 bits to acknowledge
*<tt>void '''gui_gc_blit_gc'''(Gc source, int xs, int ys, int ws, int hs, Gc dest, int xd, int yd, int wd, int hd)</tt> - Blits (and Stretch with a cubic interpolation if <<tt>wd,hd</tt>> is different than <<tt>wd,hd</tt>>) from rectangle <<tt>xs,ys,ws,hs</tt>> of <tt>source</tt> to rectangle <<tt>xd,yd,wd,hd</tt>> of <tt>dest</tt>.
* C4000008 (R/W): Interrupt enable register
* C4000100-C40001DF: Per-channel registers (channel 0 starts at C4000100, channel 1 at C4000120, etc.)
** +00 (R/W): Set bit 0 to start measurement; interrupt status bits 0 and 1 will be set when complete and the value will be stored in +10 register. Other commands do exist, including some that write to memory.
** +04 (R/W): Unknown (28 bits)
** +08 (R/W): Number of halfwords to write (25 bits)
** +0C (R/W): Base address (word-aligned)
** +10 (R): Read measured voltage. Scale for channels 1 and 2 is 155 units = 1 volt; scale for other channels is 310 units = 1 volt
** +14 (R/W): Speed (10 bits, set to AHB clock speed / 40000)


''Notice: On OS 3.1 CX/CM, when stretching only, there is a bug that distorts the source rectangle depending on the destination ratio. Even the OS shows this bug, for example Ctrl+N, 2, Ctrl+Up will not center the axes whereas on OS 3.2 it will.''
==C8010000 - Triple DES encryption==


*<tt>void '''gui_gc_blit_buffer'''(Gc gc, char * buffer, int xb, int yb, int wb, int hb)</tt> - Blits a rectangle <<tt>xb,yb,wb,hb</tt>> from <tt>buffer</tt> to the given <tt>gc</tt>. Strangely, <tt>buffer</tt> has to be 320 pixels wide in order to have the correct offsets. Also, <tt>buffer</tt> has to be allocated according to the platform: On Clickpads/Touchpads use 1/2bpp (thus, 160xH), on CM/CX use 2bpp (thus 320x2xH).
Implements the [http://en.wikipedia.org/wiki/Triple_DES Triple DES encryption algorithm].


''Notice: In order to be compatible with Clickpads/Touchpads (1/2 bpp vs 2bpp), <tt>x</tt> has to be a the same parity of the current Region's <tt>x</tt>''
* C8010000 (R/W): Right half of block
* C8010004 (R/W): Left half of block. Writing this causes the block to be encrypted/decrypted.
* C8010008 (R/W): Right 32 bits of key 1
* C801000C (R/W):
** Bits 0-23: Left 24 bits of key 1
** Bit 30: Set to 0 to encrypt, 1 to decrypt
* C8010010 (R/W): Right 32 bits of key 2
* C8010014 (R/W): Left 24 bits of key 2
* C8010018 (R/W): Right 32 bits of key 3
* C801001C (R/W): Left 24 bits of key 3


unsigned size = 320 * 15 * 2;
==CC000000 - SHA-256 hash generator==
if (!lcd_isincolor()) size >>= 2;
char * buff = malloc(size);
memset(buff, 0x44, size);
/* Draws a green rectangle at <11,20> of size <15,15> */
gui_gc_setRegion(gc, 11, 20, 15, 15, 0, 0, 15, 15);
gui_gc_blit_buffer(gc, buff, 1, 0, 15, 15);
free(buff);


You may notice the spare space unused. Thus, this method is only recommended to be use on fullscreen buffers. For example, this method is used by the internal 3D engine of the OS.
Implements the [http://en.wikipedia.org/wiki/SHA_hash_functions SHA-256 hash algorithm], which is used in cryptographic signatures.


===Others===
* CC000000 (R): Busy if bit 0 set
*<tt><s>void show_dialog_box2(int winid, const char *utf8_title, const char *utf8_msg)</s></tt>: displays a dialog box of title <tt>utf8_title</tt> containing <tt>utf8_msg</tt>. <tt>utf8_title</tt> and <tt>utf8_msg</tt> are C strings converted with <tt>ascii2utf16()</tt>. <tt>winid</tt> must be 0 (''deprecated since Ndless 2.0 and replaced with libndls's show_msgbox'').
* CC000000 (W): Write 0x10 and then 0x0 to initialize. Write 0xA to process first block, 0xE to process subsequent blocks
*<tt>int read_unaligned_longword(void *ptr)</tt>
* CC000008 (R/W): Some sort of bus write-allow register? If a bit is set, it allows R/W access to the registers of the peripheral, if clear, R/O access only. Don't know what it's doing here, but it's here anyway.
*<tt>int read_unaligned_word(void *ptr)</tt>
** Bit 8: [[#CC000000 - SHA-256 hash generator]]
** Bit 10: ?
* CC000010-CC00004F (R/W): 512-bit block
* CC000060-CC00007F (R): 256-bit state


== NavNet ==
==DC000000 - Interrupt controller==
NavNet is the TI-Nspire specific [[USB Protocol]] and API for calc-to-calc and computer-to-calc transfers. It allows bidirectional and multi-service exposition with connections initiated from the calculator or the computer, abstracting the host/device orientation of USB. The protocol takes care of acknowledgement, and supports network of calculators built with the TI-Nspire™ Navigator System. Standard services such as file transfer or directory listing are available, and custom services can be implemented.
See [[Interrupts]]. The controller is a [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0181e/index.html PL190].
 
Request and response messages contain arbitrary data of at most 254 bytes. The convention for the [[USB Protocol#Services|standard services]] is:
* a single command byte at the beginning of the request packet, with optional parameters data
* a single acknowledgement byte at the beginning of the request packet, with optional response data, ''or'' a 2 byte error code
NavNet does not help with the construction of request and response data.
 
Starting from v3.1 r893 Ndless and the Ndless SDK support a subset of the NavNet API. Windows (with Computer Link or Student Software) is required on the computer side, but a Linux/Mac OS X version based on the [http://lpg.ticalc.org/prj_tilp/ TiLP libraries] may be available in the future. Bidirectional calc-to-calc transfers don't appear to fully work yet as there seems to be limitations in NavNet that make one or the two calculator reboot in some conditions.
 
Ndless's NavNet [https://www.unsads.com/scm/svn/nsptools/Ndless/trunk/arm/tests/navnet automated tests] (guest/guest) is a good start to understand the API. The NdlessEditor of the Ndless SDK also shows an example of computer-to-calc file transfer supporting the ''Tools > Transfer the program to calc'' menu. The source code is available in <tt>cmd_tools/navnet_cmd</tt>. A startup script is used on the computer side that puts navnet.dll onto the PATH.
 
=== The NavNet API ===
The functions are directly available for the TI-Nspire. For computer connection, the <tt>navnet.h</tt> and <tt>libnavnet.a</tt> library (wrapper for the navnet.dll library) in <tt>ndless_pc/</tt> of the Ndless SDK must be used.
 
All functions return a number >= 0 in case of success that should be checked.
 
*<tt>int16_t TI_NN_Init(const char *opts)</tt>: (computer side) starts the NavNet stack with parameters <tt>opts</tt>. You'll typically use <tt>-c 1 -d 0</tt>, where the -c and -d switches are the log level respectively for the console and the NavNet debug file. Note that the stack cannot be started if Student Software is already running, and transfers without initialization may interfer with transfers from Student Software.
*<tt>int16_t TI_NN_Shutdown(void)</tt>: (computer side) stops the NavNet stack.
*<tt>int16_t TI_NN_RegisterNotifyCallback(uint32_t filter_flags, void (*cb)(void))</tt>: (computer side, broken on calculator side) register for connection events. A connection event is published even if a device was plugged in before the NavNet stack initialization. <tt>filter_flags</tt> should be zero. The parameters passed to the callback function are currently unknown. The computer program should wait for a notification after a <tt>TT_Init()</tt> and before a node enumeration, else the enumeration will fail.
*<tt>nn_oh_t TI_NN_CreateOperationHandle(void)</tt>: create an operation handle to be used with some NavNet functions.
*<tt>int16_t TI_NN_DestroyOperationHandle(nn_oh_t oh)</tt>: destroy an operation handle.
*<tt>int16_t TI_NN_NodeEnumInit(nn_oh_t oh)</tt>: initiates a node (computer or device) enumeration. Enumeration is required to find the partner computer or device.
*<tt>int16_t TI_NN_NodeEnumNext(nn_oh_t oh, nn_nh_t *nh)</tt>: writes the node handle of the next partner computer or device found to <tt>nh</tt>. The first node handle can be used when assuming a single node network.
*<tt>int16_t TI_NN_NodeEnumDone(nn_oh_t oh)</tt>: terminates a node enumeration.
*<tt>int16_t TI_NN_Connect(nn_nh_t nh, uint32_t service_id, nn_ch_t *ch)</tt>: connects to a remote service with service identifier <tt>service_id</tt> (see the list of [[USB_Protocol#Service_identifiers|standard identifiers]], or use a custom service id for custom services). Note that this functions only set up the client node and doesn't transmit any packet.
*<tt>int16_t TI_NN_Disconnect(nn_ch_t ch)</tt>: disconnects from a remote service by sending a disconnection packet.
*<tt>int16_t TI_NN_Write(nn_ch_t ch, void *buf, uint32_t data_size)</tt>: writes a packet to a remote service. The payload is <tt>data_size</tt> long and pointed to by <tt>buf</tt>.
*<tt>int16_t TI_NN_Read(nn_ch_t ch, uint32_t timeout_ms, void *buf, uint32_t buf_size, uint32_t *recv_size)</tt>: waits until a packet is received or a timeout. The size of the packet received is written to <tt>recv_size</tt>. Data is written to <tt>buf</tt> of <tt>buf_size</tt> bytes long. A packet size can be at most <tt>TI_NN_GetConnMaxPktSize()</tt>.
*<tt>uint32_t TI_NN_GetConnMaxPktSize(nn_ch_t ch)</tt>: returns the maximum packet size for request and response.
*<tt>int16_t TI_NN_StartService(uint32_t service_id, void *data, void (*cb)(nn_ch_t ch, void *data))</tt>: exposes a service. <tt>data</tt> will be passed as the <tt>data</tt> parameter of the callback function, and may be NULL. The service identifier musn't conflict with [[USB_Protocol#Service_identifiers|standard identifiers]].
*<tt>int16_t TI_NN_StopService(uint32_t service_id)</tt>: stops exposing a service.
*<tt>int16_t TI_NN_PutFile(nn_nh_t nh, nn_oh_t oh, const char *local_path, const char *remote_path)</tt>: transfers a file from <tt>local_path</tt> to <tt>remote_path</tt>. The local path must be absolute. The remote path is relative to the <tt>/documents</tt> TI-Nspire folder. You must first <tt>TI_NN_Connect()</tt> to service 0x4060 before using it.
 
The following functions are not yet implemented:
*TI_NN_UnregisterNotifyCallback
*TI_NN_InstallOS
*TI_NN_GetNodeInfo
*TI_NN_GetNodeScreen
*TI_NN_CopyFile
*TI_NN_Rename
*TI_NN_RmDir
*TI_NN_MkDir
*TI_NN_DeleteFile
*TI_NN_GetFileAttributes
*TI_NN_DirEnumDone
*TI_NN_DirEnumNext
*TI_NN_DirEnumInit
*TI_NN_GetFile

Revision as of 18:43, 7 March 2020

00000000 - Boot1 ROM

128kB of on-chip ROM.

10000000 - SDRAM

32 MiB SDRAM on CM or 64 MiB on CX. Managed by 0x8FFF0000.

8FFF0000 - SDRAM controller

A DMC-340 r1p0.

8FFF1000 - NAND controller

A PL351 r1p2.

90000000 - General Purpose I/O (GPIO)

See GPIO Pins

90010000 - Fast timer

The same interface as 900C0000/900D0000, but runs at the speed of the APB clock (22.5MHz) rather than 32kHz. See Second timer for more info.

90020000 - Serial UART

PL011.

90030000 - Unknown

Probably some kind of hash/crypto thing.

90040000 - SPI controller

A PL022 for communicating with the LCD panel controller, which is probably an ILI9341 or ILI9340. Used on CX HW-W+ only.

90050000 - I2C controller

The Touchpad on the CX is accessed through this controller. See Keypads#Touchpad I²C for protocol details. It seems to be a Synopsys Designware I2C adapter.

  • 90050000 (R/W): Control register?
  • 90050004 (?): ?
  • 90050010 (R/W): Data/command register
  • 90050014 (R/W): Speed divider for high period (standard speed) OS: 0x9c
  • 90050018 (R/W): Speed divider for low period (standard speed) OS: 0xea
  • 9005001c (R/W): Speed divider for high period (high speed) OS: 0x3b
  • 90050020 (R/W): Speed divider for low period (high speed) OS: 0x2b
  • 9005002c (R/W?): Interrupt status
  • 90050030 (R/W): Interrupt mask
  • 90050040 (R/W): Interrupt clear. Write 1 bits to clear
  • 9005006c (R/W): Enable register
  • 90050070 (R): Status register
  • 90050074 (R?/W): TX FIFO?
  • 90050078 (R?/W): RX FIFO?
  • 900500f4 (?): ?
  • 90050080 (?): ?

90060000 - Watchdog timer

Possibly an ARM SP805 or compatible.

90090000 - Real-Time Clock (RTC)

Similar to the ARM PrimeCell PL031, but interrupt registers are different.

  • 90090000 (R): Current time, increments by 1 every second.
  • 90090004 (R/W): Alarm value. When the time passes this, interrupt becomes active.
  • 90090008 (R/W): Sets the value of 90090000 (clock will not read new time until a couple seconds later). Reads last value written.
  • 9009000C (R/W): Interrupt mask (1-bit)
  • 90090010 (R/W): Masked interrupt status, reads 1 if interrupt active and mask bit is set. Write 1 to acknowledge.
  • 90090014 (R): Status
    • Bit 0: Time setting in progress
    • Bit 1: Alarm setting in progress
    • Bit 2: Interrupt acknowledgment in progress
    • Bit 3: Interrupt mask setting in progress

900A0000 - Miscellaneous

  • 900A0000 (R): ? 0x101
  • 900A0004 (R/W): Set bit 0x20 to enable TI-84+ keypad link port. Other bits likely control functions of peripherals as well.
  • 900A0008 (W): Write a 2 to cause a hardware reset
  • 900A0010 (R/W): Fast timer interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
  • 900A0014 (R/W): Fast timer interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0010] should trigger an IRQ.
  • 900A0018 (R/W): Timer 1 interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
  • 900A001C (R/W): Timer 1 interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0018] should trigger an IRQ.
  • 900A0020 (R/W): Timer 2 interrupt status/acknowledge (6-bit). Write "1" bits to reset the corresponding interrupt requests.
  • 900A0024 (R/W): Timer 2 interrupt mask (6-bit). Set bits to 1 if the corresponding bits in [900A0020] should trigger an IRQ.
  • 900A0028-900A002C (R): These registers together give a 64-bit number (28 is low, 2C is high) which comprises 56 data bits and 8 parity checking bits, allowing any single-bit error in it to be detected and corrected.
    • Parity bit 0: Check of all data bits
    • Parity bits 1, 2, 4, 8, 16, and 32: Checks of the data bits whose positions, expressed in binary, have that respective bit set.
    • Data bits 3, 5-7, 9-15, 17-31, and 33-55: Serial number (middle part of the calculator's Product ID)
    • Data bits 56-57: Unknown
    • Data bits 58-62: "ASIC user flags"; must match the 80E0 field in an OS image. 01 = CAS, 00 = non-CAS, 03 = CM CAS, 02 = CM non-CAS.
    • Parity bit 63: Check of parity bits 1, 2, 4, 8, 16, and 32.
  • 900A0F04 (R/W): Unknown; Boot1 sets this to 0x1D

900B0000 - Power management

  • 900B0000 (R/W): Clock speed load value
  • 900B0004 (R/W): 25-bit mask of which events may wake the hardware up from low-power mode.
    • Bit 10: Unknown, probably the TI-84 Plus link port
    • Bit 12: RTC interrupt
    • Bit 13: Unknown, probably ON key or USB activity
    • Bit 17: Battery door open/close?
    • Bit 23: Keypad remove/replace?
  • 900B0008 (R/W): Reason for waking up from low-power mode. Write "1" bits to acknowledge.
  • 900B000C (R/W): Clock speed control. Write 4 to set the clock speed according to the value in 900B0000. If interrupts are disabled the new clock speed will only become effective after exiting the program. Write 3A to enter low-power mode; this requires various peripherals to be prepared and probably works by stopping the clock.
  • 900B0010 (R/W): ON interrupt mask (1-bit). 1 if ON interrupt should be serviced or 0 if not.
  • 900B0014 (R/W): Bit 0 is set if ON interrupt is requested. Bit 1 also causes an interrupt, but the cause is unknown (and it is not masked by [900B0010]) - it is set after writing 4 to 900B000C. Write "1" bits to reset the requests.
  • 900B0018 (R/W): Disable bus access to peripherals. Reads will just return the last word read from anywhere in the address range, and writes will be ignored.
  • 900B0020 (R/W): ? - Possibly another peripheral bus access disable register.
  • 900B0024 (R): Reads current clock speed value (see 900B0000 for details)
  • 900B0028 (R): Bit 4 (0x10) clear when ON key pressed

900C0000 - First timer

Configured as ~105 Hz timer by the OS (only used in the TI-84+ emulator). Same port structure as Second timer.

900D0000 - Second timer

Two timers are located here, but only the first can generate IRQs. IRQ status/mask is located at [900A0020]. Configured as a ~100 Hz timer by the OS.

Timer is a SP804.

900E0000 - Keypad controller

See also Keypads for information about the keypads themselves.

  • 900E0000 (R/W):
    • Bits 0-1: Scan mode
      • Mode 0: Idle.
      • Mode 1: Indiscriminate key detection. Data registers are not updated, but whenever any key is pressed, interrupt bit 2 is set (and cannot be cleared until the key is released).
      • Mode 2: Single scan. The keypad is scanned once, and then the mode returns to 0.
      • Mode 3: Continuous scan. When scanning completes, it just starts over again after a delay.
    • Bits 2-15: Number of APB cycles to wait before scanning each row
    • Bits 16-31: Number of APB cycles to wait between scans
  • 900E0004 (R/W):
    • Bits 0-7: Number of rows to read (later rows are not updated in 900E0010-900E002F, and just read as whatever they were before being disabled)
    • Bits 8-15: Number of columns to read (later column bits in a row are set to 1 when it is updated)
  • 900E0008 (R/W): Keypad interrupt status/acknowledge (3-bit). Write "1" bits to acknowledge.
    • Bit 0: Keypad scan complete
    • Bit 1: Keypad data register changed
    • Bit 2: Key pressed in mode 1
  • 900E000C (R/W): Keypad interrupt mask (3-bit). Set each bit to 1 if the corresponding event in [900E0008] should cause an interrupt.
  • 900E0010-900E002F (R): Keypad data, one halfword per row.
  • 900E0030-900E003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown.
  • 900E0040 (R/W): Interrupt enable. Bits unknown but seems to be related to touchpad. Causes interrupt on touchpad touched.
  • 900E0044 (R/W): Interrupt status. Bits unknown. Write 1s to acknowledge.
  • 900E0048 (R/W): Unknown

900F0000 - HDQ/1-Wire and LCD contrast

The HDQ/1-Wire registers resemble those on the TI OMAP processors, and are possibly used to communicate with the wireless cradle. There is no conceivable reason for the LCD contrast register to be part of the same module, but here it is. :-(

  • 900F0004 (W): Transmitted data
  • 900F0008 (R): Received data
  • 900F000C (R/W): Control/status
  • 900F0010 (R): Interrupt status (automatically acknowledged when read)
  • 900F0020 (R/W): LCD contrast/backlight. Valid range for contrast: 0x11a to 0x1ce; normal value is 0x174. However, it can range from 0x100 (backlight off) to about 0x1d0 (about max brightness).

90110000 - LED

  • 90110B00 (R/W): Control register
    • Bit 0: Set this bit to enable green light blink data. If green blink data iteration is not on, the green light state is read from bit 0 of green blink data.
    • Bit 1: Set this bit and bit 6 to enable green blink data iteration.
    • Bit 2: Set this bit to force green light off. Overrides bit 4.
    • Bit 3: Set this bit to force red light off. Overrides bits 5 and 13.
    • Bit 4: Set this bit to force green light on.
    • Bit 5: Set this bit to force red light on.
    • Bit 6: See this bit and bit 1 to enable green blink data iteration. Reset before modifying green blink data or delay.
    • Bit 9: Set this bit to enable red light blink data. If red blink data iteration is not on, the red light state is read from bit 0 of red blink data.
    • Bit 10: Set this bit and bit 12 to enable red blink data iteration.
    • Bit 12: Set this bit and bit 10 to enable red blink data iteration. Reset before modifying red blink data or delay.
    • Bit 13: Forces red light on if bit 4 is 0, or red light off if bit 4 is 1. (?)
  • 90110B04 (R/W): Green blink data. 32 bits of on and off state, represented by 1 and 0. Iteration is done from bit 31 to bit 0 repeatedly.
  • 90110B08 (R/W): Green blink delay (negative). OS sets this to -2048.
  • 90110B0C (R/W): Red blink data. 32 bits of on and off state, represented by 1 and 0. Iteration is done from bit 31 to bit 0 repeatedly.
  • 90110B10 (R/W): Red blink delay (negative). OS sets this to -2048.

Note: If red and green lights are on at the same time, the color becomes yellow.

A4000000 - Internal SRAM

0x20000 bytes SRAM, managed by the controller at 0xB8000000.

B0000000 - USB OTG controller

The OTG controller on all models is a ChipIdea-based dual-role USB controller. It only supports full speed communications so the PFSC bit (bit 24) must be set in the PORTSC register when in host mode. Otherwise, it'll attempt to connect at high speed for devices that support it and will never succeed in enumerating them.

Documentation can be found in the IMX233 reference manual. The host interface is, again, based on EHCI; but the register defaults are different. The addresses have been adjusted from the ones contained in the IMX233 reference manual.

  • Module identification registers
    • B0000000: HW_USBCTRL_ID - default 0xE241FA05
    • B0000004: HW_USBCTRL_HWGENERAL - default 0x00000015
    • B0000008: HW_USBCTRL_HWHOST - default 0x10020001
    • B000000C: HW_USBCTRL_HWDEVICE - default 0x0000000B
    • B0000010: HW_USBCTRL_HWTXBUF - default 0x40060910
    • B0000014: HW_USBCTRL_HWRXBUF - default 0x00000710
  • Capability registers
    • B0000100: HW_USBCTRL_CAPLENGTH - default 0x01000040
    • B0000104: HW_USBCTRL_HCSPARAMS - default 0x00010011
    • B0000108: HW_USBCTRL_HCCPARAMS - default 0x00000006
    • B0000120: HW_USBCTRL_DCIVERSION - default 0x00000001
    • B0000124: HW_USBCTRL_DCCPARAMS - default 0x00000185 (host-capable, device-capable, 5 endpoints)
  • Operational registers
    • B0000140: HW_USBCTRL_USBCMD - default 0x00080B00 in host mode, 0x00080000 in device mode
    • B0000144: HW_USBCTRL_USBSTS - default 0x00001000 in host mode, 0x00000000 in device mode
    • B0000148: HW_USBCTRL_USBINTR - default 0x00000000
    • B000014C: HW_USBCTRL_FRINDEX - default 0x00000000
    • B0000154: (in host mode) HW_USBCTRL_PERIODICLISTBASE - default 0x00000000
    • B0000154: (in device mode) HW_USBCTRL_DEVICEADDR - default 0x00000000
    • B0000158: (in host mode) HW_USBCTRL_ASYNCLISTADDR - default 0x00000000
    • B0000158: (in device mode) HW_USBCTRL_ENDPOINTLISTADDR - default 0x00000000
    • B000015C: HW_USBCTRL_TTCTRL - default 0x00000000
    • B0000160: HW_USBCTRL_BURSTSIZE - default 0x00001010
    • B0000164: HW_USBCTRL_TXFILLTUNING - default 0x000000000
    • B000016C: HW_USBCTRL_IC_USB - default 0x00000000
    • B0000170: HW_USBCTRL_ULPI - default 0x00000000
    • B0000178: HW_USBCTRL_ENDPTNAK - default 0x00000000
    • B000017C: HW_USBCTRL_ENDPTNAKEN - default 0x00000000
    • B0000184: HW_USBCTRL_PORTSC1 - default 0x10000000
    • B00001A4: HW_USBCTRL_OTGSC - default 0x00000120
    • B00001A8: HW_USBCTRL_USBMODE - default 0x00000000
    • B00001AC: HW_USBCTRL_ENDPTSETUPSTAT - default 0x00000000
    • B00001B0: HW_USBCTRL_ENDPTPRIME - default 0x00000000
    • B00001B4: HW_USBCTRL_ENDPTFLUSH - default 0x00000000
    • B00001B8: HW_USBCTRL_ENDPTSTAT - default 0x00000000
    • B00001BC: HW_USBCTRL_ENDPTCOMPLETE - default 0x00000000
    • B00001C0: HW_USBCTRL_ENDPTCTRL0 - default 0x00100010
    • B00001C4: HW_USBCTRL_ENDPTCTRL1 - default 0x00000000
    • B00001C8: HW_USBCTRL_ENDPTCTRL2 - default 0x00000000
    • B00001CC: HW_USBCTRL_ENDPTCTRL3 - default 0x00000000
    • B00001D0: HW_USBCTRL_ENDPTCTRL4 - default 0x00000000

Role switching

During role switching some GPIO output registers are modified.

  • GPIO2:
    • Active low.
    • Controls VBUS/pull-up (drives VBUS to 5v for host mode)
  • USB-B: GPIO6
    • Active low.
    • Probably controls charging from USB

B4000000 - USB HOST controller

Same port structure as B0000000.

B8001000 - SRAM Controller

A PL352 r1p2.

C0000000 - LCD controller

A PL111.

C4000000 - Analog-to-Digital Converter (ADC)

Used to check various voltages. Channels 1 ("VBATT"), 2 ("VSYS"), and 4 ("B12") are used to check the battery status; channel 3 is used to determine which keypad is in use.

  • C4000000 (R): Masked interrupt status (4 bits per channel: bits 0-3 are for channel 0, etc)
  • C4000004 (R/W): Raw interrupt status, write 1 bits to acknowledge
  • C4000008 (R/W): Interrupt enable register
  • C4000100-C40001DF: Per-channel registers (channel 0 starts at C4000100, channel 1 at C4000120, etc.)
    • +00 (R/W): Set bit 0 to start measurement; interrupt status bits 0 and 1 will be set when complete and the value will be stored in +10 register. Other commands do exist, including some that write to memory.
    • +04 (R/W): Unknown (28 bits)
    • +08 (R/W): Number of halfwords to write (25 bits)
    • +0C (R/W): Base address (word-aligned)
    • +10 (R): Read measured voltage. Scale for channels 1 and 2 is 155 units = 1 volt; scale for other channels is 310 units = 1 volt
    • +14 (R/W): Speed (10 bits, set to AHB clock speed / 40000)

C8010000 - Triple DES encryption

Implements the Triple DES encryption algorithm.

  • C8010000 (R/W): Right half of block
  • C8010004 (R/W): Left half of block. Writing this causes the block to be encrypted/decrypted.
  • C8010008 (R/W): Right 32 bits of key 1
  • C801000C (R/W):
    • Bits 0-23: Left 24 bits of key 1
    • Bit 30: Set to 0 to encrypt, 1 to decrypt
  • C8010010 (R/W): Right 32 bits of key 2
  • C8010014 (R/W): Left 24 bits of key 2
  • C8010018 (R/W): Right 32 bits of key 3
  • C801001C (R/W): Left 24 bits of key 3

CC000000 - SHA-256 hash generator

Implements the SHA-256 hash algorithm, which is used in cryptographic signatures.

  • CC000000 (R): Busy if bit 0 set
  • CC000000 (W): Write 0x10 and then 0x0 to initialize. Write 0xA to process first block, 0xE to process subsequent blocks
  • CC000008 (R/W): Some sort of bus write-allow register? If a bit is set, it allows R/W access to the registers of the peripheral, if clear, R/O access only. Don't know what it's doing here, but it's here anyway.
  • CC000010-CC00004F (R/W): 512-bit block
  • CC000060-CC00007F (R): 256-bit state

DC000000 - Interrupt controller

See Interrupts. The controller is a PL190.