This page was written for people who are interested in not just a description of the whole system which as of its nature doesn't go into much detail, but for those who like to catch a glimpse below the surface. Nonetheless this won't cover all details, for those it's imperative to look at the several specifications or even the source code. But as that's a lot of material which partly isn't even translated (i.e. you have to understand German to understand some of those documents) this text might help a great deal in understanding the basic technical background. If after reading this text you still have any questions you can't find an answer for, don't hesitate to contact us.
In order to have the server communicate with one or more clients, a specification or protocol is necessary. Our protocol consists of three layers called low, intermediate and high level protocol which will now each be further detailed. An even more comprehensive explanation can be found in the official paper.
The low-level protocol specifies how single bytes get from server to client and vice versa. Actually the specification is rather short as we use the commonly known RS232 protocol which luckily is supported by both the server (PC) and microcontroller. RS232 transfers data via one line without a clock signal (this is called asynchronously). As of this both parties have to agree on a transmission rate which in our case is 19.2kbit/s. In order to realize the beginning of a byte, a start bit is sent, after start bit and (in our case) 8 data bits comes a stop bit to allow detection of the next start bit.
The Intermediate-level protocol's task is to form packets out of single data bytes. These packets contain information about sender and recipient which is necessary if you have more than just two parties communicate with each other. Also included is a checksum which makes sure that the data has been transmitted correctly, the length of the packet, a multi-packet counter which will be explained later and the Content-ID which specifies what type of content the data part forms. The checksum is calculated using the well-known CRC-8 algorithm. As we use a byte to indicate the length of a single packet, the data part can not exceed a length of 248 byte which would only allow for few data. To overcome this weakness, we used multi-packets: The data is cut into several pieces and then transferred in consecutive single-packets. The multi-packet counter tells the recipient which single-packet or part of the multi-packet it receives. The recipient then only has to concatenate the pieces of data in the right order to get the whole data part (which then can be up to 62kB long). As we use noisy radio transmission it's also up to the intermediate level protocol to assure the detection of packet starts. This is accomplished by sending an FFh (binary 255) to gain inter-byte synchronisation and a "U" which is basically a randomly selected start/escape char which happens to be a binary 1010101010 on RS232. Altogether the packet format is the following:
In a point-to-point protocol everything one party sends is automatically received by the other, also data can be sent at any time. But as we have a network with at least 2 parties, it's necessary to specify who is when allowed to transmit. Our approach is based on a loop with the server in a special position. During login the server assigns every client an address, which is simply a number between 3 and 253; the server itself always has number 1. The adresses for the clients might be assigned randomly, but for the system to work as intended it is necessary to assign them consecutive numbers, i.e. 3, 4, 5 or 111, 112, 113. The server starts a new loop by sending data to the clients. Actually this isn't necessary for the system to work but it's currently done this way. Also it's not necessary to send packets to all clients on the network, but as well, it's done this way. If there is no real data which could be sent, so called empty-packets are sent. After receiving data from the server, the clients are given order to send their data to the server. To avoid confusion, the first client in the row (the one with the lowest address) is given explicit order to send, this packet is called Sendefreigabe. As the other clients are listening all the time, they should receive the packet of the first client. The second client realizes that this was the client with the row position just before itself, so this client is now going to send. This goes on until the last client in the loop has sent its data. If one client doesn't send because it didn't receive the packet of the last client, the system would stop. To avoid this the server monitors the transfers and if one client doesn't send, it's given the order to do so. If all clients have sent, new clients may login, otherwise the loop starts from the beginning.
As mentioned above, during radio login each client gets a number or address from the server. But as clients who aren't logged in yet aren't allowed to transmit at any time, there has to be a mechanism to let them express their wish to be in with the crowd :-) This is again controlled by the server. Login sequence is initiated by the server sending a special packet which not-yet-logged-in clients are waiting for all the time. If they receive such a packet, the client sends back another packet containing information about client software version, connected calculator type and most importantly a username. If the server receives this packet, it sends back an acknowledgement packet that contains the username and the assigned address. The username is sent to avoid assigning the same number to two clients which login at the same time, also it allows a distinction between users which is necessary i.e. for e-mail setup and the internal messaging system. After the login procedure the server continues doing whatever is next, it is impossible that a client sends a packet after receiving the login packet from the new client, as login packets are always sent with (temporary) sender address 255 and address 255+1=0 isn't assigned to clients. It's also up to the server if and when it starts the login sequence, currently this is done at the end of each high-level-loop. In most cases there is no client who wants to login so if the server gets no reply within a short time, it assumes that no client wishes to login and continues as usual.
The TI<->µC protocol specifies the way data gets from microcontroller to TI and vice versa. As the radio protocol the microcontroller has to handle is very time sensitive and as the TI always has to handle user input in the background the communication between those two parties should be as time uncritical as possible whilst staying simple, speed wasn't much of an issue during considerations. However, to improve things a modified protocol has been thought of but not yet realized; information on this can be found at the according project future section.
Transferring bytes is done similar to the way TI uses to transfer variables between TI and computer or between two TIs. The calculator has two bi-directional I/O lines which are wired to two I/O pins of the microcontroller. If, say, the TI wishes to transfer a binary 1 it pulls the red wire low to 0V which is monitored by the microcontroller and acknowledged by pulling the white wire low. As soon as the calculator gets this reply it returns the red wire back to 5V which is again acknowledged by the microcontroller putting the white wire back to 5V. If the TI wanted to transfer a binary 0 instead of pulling the red wire low it pulls the white wire to 0V and in all following actions the wires are interchanged as well. The 8 bits of a byte are transferred consecutively, most significant bit first.
All transfers are based on packets. A tranfer is initiated by a START command which is actually the same as sending a binary 1 with low-level protocol. After this come several bytes in the following order:
Several packet type identifiers exist, i.e. 30h specifies an <ACK> packet, 21h means <µC logged out>. More than half of the packets currently defined don't have any further data attached which means the packet type identifier is all the important part.
Basically the high-level protocol just features the flow of packets in several situations like login, logout or if radio data has been received or has to be transmitted. For all these situations have a look at the specification itself, there you'll also find all the defined packet type identifiers.
The most interesting part is the one about sending/receipt of radio packets. If the TI wishes to send a radio packet to the server (for example the number of the selected menu entry, text of the edit field, ...) it sends a <TI send radio packet> with the data included to the µC. The microcontroller then saves this data in a buffer and transmits it at that time the radio high-level protocol allows it to do so. Afterwards the µC sends a <µC sent radio packet> to the TI.
The microcontroller always listens to radio data packets which might be for the connected TI. If it receives such one, the packet is stored in a buffer and the TI is informed about this: A <µC received radio packet> is sent to the calculator. This packet informs the TI that there is new content on its way to be displayed and therefor further user input is to be prohibited. Also this means that the TI may not read out the microcontroller's buffer anymore because of inconsistencies. As explained in the section radio intermediate-level protocol radio data can be split up into several packets (multi-packets). If the microcontroller received all the data which might have been transported in several single packets, it issues a <µC received complete radio (multi-)packet> which informs the TI about this and which also carries information about the length and Content-ID of the data. When the calculator receives this packet it is again allowed to read out the buffer of the microcontroller and to display the new content. This is done by the packets <TI request radio packet> and <µC send radio packet>.
TI client software
The TI client software's duty is to communicate with a connected microcontroller (if any), receive and display data, wait for user input and send it to the microcontroller.
In the beginning the program "scans" the linkport for a connected microcontroller and if none is connected waits until one gets or until the user aborts. If a microcontroller is connected a handshake is done which, if successful, results in displaying software versions and displaying an edit field to let the user enter his/her username. This username is then sent to the server via the microcontroller. Now the TI can only wait for the microcontroller telling the TI that it is logged into the network. Now the software enters the main loop which can either be terminated by the user wishing to log out or by the server kicking the client.
In the main loop the calculator first checks whether the microcontroller wishes to send a TI<->µC packet. If this is the case, the according communication routine is called. Afterwards some flags are checked that were probably set by the microcontroller communication routines and that inform the main loop about TI<->µC communication status. If necessary the main status information like "Sent" & "Received" gets displayed. If new data from the server has arrived, an appropriate routine is called that gets the data from the microcontroller and stores it in the calculator's memory. Afterwards a routine to display (or incase a key has been pressed: to update) the content is called.
This routine first of all examines what kind of content is to be displayed. After this decision was made the according display routine checks whether the data packet had just arrived which would result in initializing the display or whether it just has to be updated due to a key pressed by the user.
Last but not least some very technical information: As the current version can still be considered to be at development stage, all variables and buffers are hard-coded in the program memory. Also for example only packets with a maximum number of 256 byte (the buffer length) can be received and displayed by the calculator, however we haven't found this to be an actual limitation. The program code is split up into several files to keep it somewhat easier to maintain, if you're really interested in seeing how everything works, just look at the code yourself. It was developed sing Jeremy Goetsch's great Assembly Studio 8x 4.0, so trying to assemble it using TASM might result in errors, but I haven't actually tried.
TI server software
Incase Alexander gets some spare time in the future he has to update this section as he's the only one who's supposed to really know what to write about. Right now all I (Burkart) can tell you about the server software is that it's programmed in Borland Delphi 5. Well... Um, and there have been a few complete rewrites for reasons I don't know of. But again, Alexander will :-) To interface the serial port, a component called Varian Async is used.