![]() 1909 Old Mountain Creek Road, Greenville, SC 29609 tel:864.233.8330 fax:864.233.8331 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Floating Point MathGeneral Info / DetailedMain Features are:
Available Floating Point operations are:
Values are passed to and from CP-FP as 16 bit integers and free of any conversion routines. The returned data can also be two separate integers of whole and fraction parts to allow fast simple display code with a decimal point. To further minimise the host's involvement, frequently used values can be stored on-chip in EEPROM. The same holds true for calculation sequences which can be stored as programs. When establishing such a program it must be expressed within the constraints of the host's compiler and its 'ShiftOut' command format. Clearly the calculation cannot be presented as a fully bracketed formula, but because of an ample supply of FP registers and their freedom of use, the calculation can be spelt out in an equally explicit manner within those constraints. Of the 15 FP registers, 7 are in EEPROM. Each register can be the source or destination for any Math operation, and even both. Because every register is capable of all operations, the need to maneuver data in eliminated. That means that the program sequence is simple to write, and is readily understood at a later date, or by others. Once debugged, it is easily converted into an EEPROM program. From there on, the application can merely update associated variables and run the EEPROM program, without the customary need for hand-holding. The result can be collected as a user scaled integer, or as convenient whole and fraction integers for display. To maximise the utilisation of EEPROM memory, each program can also chain to another program. The absolute maximum single program length is 28 bytes and is equivalent to 14 Floating Point operations.
Example Writing User Program for: 'SquareRoot( Reg0^2 + Reg1^2)Shiftout DPin, CPin, MsbFirst, [WrProg+3, Mul+0,$00, Mul+1,$11, Add+6,$01, SqRt+6,$6, RunProg+0]'WrProg', 'Mul' etc have all been equated
to byte values that have their least significant nibble equal to zero. The
'+3' etc. then gets loaded into that Nibble with any standard compiler. 'Interpret Program3 like this: 'WrProg+3
Write into Program3 the following: The last line passes execution to program 0. That program in the example code splits a FP register into Whole & Fraction 16 bit Integer values for easy display. It also prepares both Integers ready for ShiftIn before clearing its 'Busy' status. Example Usage:Shiftout DPin, CPin, MsbFirst, [WrReg+0,Base\16, WrReg+1,Height\16, RunProg+3]
Shiftin DPin, CPin,
MsbPost, [Whole\16, Fraction\16] Quick Start for FP MathIt is intended that the wiring details, together with the Ready-to-run code supplied on disk, will be more than adequate to get started. The Technical Details section is not considered necessary reading for the most common usage of the co-processor. The emphasis is 'by example'. Hardware:
Software:The following programs and associated constants are pre-loaded into EEPROM ready for the user to start running. If using the BS2 software as is, remember to adjust the selected pins for CPin and DPin.
Run-time code requires nothing more than a single byte command specifying the EEPROM program to run - each such program can also be chained to another for maximum efficiency. CP-FP Technical DetailsThese notes are for users who need more details - they are not necessary to get started. The code examples supplied on disk are intended as the primary means for the user to establish efficient and reliable operation of the co-processors. Implementation:Values are passed to and from the CP as 16 bit integers and without any involvement in the conversion process. To further minimise the host's involvement, frequently used values can be stored on-chip in EEPROM. The same holds true for calculation sequences which can be stored as programs. When establishing those programs it is within the constraints of the host's compiler and its 'ShiftOut' command. Clearly the calculation cannot be presented as a fully bracketed formula, but the ample supply of FP Registers and their freedom of use allow the calculation to be spelt out in an equally explicit manner within those constraints. Of the 15 FP registers, 7 are in EEPROM. Each register can be the source or destination for any Math operation, and also act as both. That flexibility makes writing the program sequence very simple. When the calculation has been debugged, it is easily stored in EEPROM as a program. They are numbered 0-7 and each has a maximum of 11 bytes allowing up to 5 Math operations. The user has the responsibilty for observing the 11 byte limit otherwise the next program (higher number) will be overwritten. But if the next program space is not being used, it can be regarded as an extension to 23 bytes. The extra byte is gained because only one 'end of program' marker is needed. The final limit is 28 bytes when concatenating adjacent program spaces. Once saved as a program, the application only needs to supply the new variable values then issue the run command for each new calculation. The examples on disk are separated into Write and Run files for each of 3 applications. The Run files use For / Next loops to supply new data and re-calculate. The Write files are separate to avoid accidentally looping on EEPROM. Host Commands
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Command |
High |
Used by Host to: |
|
EOXfer |
22 uS |
Terminate Shiftin/Out Transfers |
|
ShowStat |
30 uS |
Show Busy status on DPin |
|
HideStat |
38 uS |
Hide Busy & release DPin |
|
ModVers |
224 uS |
Return the Model# & Version# |
|
SwReset |
256 uS |
Re-intialise |
The ShowStatus and HideStatus allow for multiple CPs to share one Data / Status pin. When a CP is not active, not being used by its Host, clearly it is not Busy. Therefore its Status would be reflected as a zero on the shared Data / Status line and prevent other CPs from using it.
Hence the need to ShowStatus at the start of an operation, and HideStatus upon completion. In between it is also used to transfer Data back and forth plus indicate when Calculations have been completed. If not sharing with other CPs then ShowStatus at power up will be sufficient.
SoftWareReset is especially valuable during program development. Any incorrect / incomplete Commands are erased to allow a fresh start - NOTE that correctly, it will also force HideStatus. The examples demonstrate a typical sequence.
|
Function |
Command Byte |
Auxiliary Byte | |||
| MS Nib | LS Nib | MS Nib | LS Nib | ||
| Add | 0 | Result Reg 0-$E | Reg 0-$E | + | Reg 0-$E |
| Subtract | 1 | Result Reg 0-$E | Reg 0-$E | - | Reg 0-$E |
| Multiply | 2 | Result Reg 0-$E | Reg 0-$E | * | Reg 0-$E |
| Divide | 3 | Result Reg 0-$E | Reg 0-$E | / | Reg 0-$E |
| SquareRoot | 4 | Result Reg 0-$E | 0 | Reg 0-$E | |
| Copy | 5 | Dest Reg 0-$E | 0 | Reg 0-$E | |
| MakeInteger | 6 | Result Reg 0-$E | 0 | Reg 0-$E | |
| ReadReg | 8 | Source Reg 0-$E | Destination 16 Bit Integer | ||
| WriteReg | 9 | Dest Reg 0-$E | Source 16 Bit Integer | ||
| RunProg | $A | Program# 0-7 | ------- | ||
| WriteProg | $E | Program# 0-7 | ------- | ||
The very flexible use of all 15 Floating Point Registers is perfect for easily sequencing through calculations. But it is easy to overlook that Registers 8 thru $E are located in EEPROM and intended to hold Constants and only be re-written occasionally - not to be used as Result Registers.
EEPROM can be re-written 100,000 times maximum - and that would only take 3-4 minutes in a tight loop, so caution is needed.
Easiest way to remember is never to use Reg#s with a Dollar $ sign in front for Result Registers, unless establishing a new Constant. Yes 8 & 9 are also EEPROM and need the same attention.
All of the supplied examples have a Routines Section at the bottom of the page. They cover from printing one or all registers, through to 'Wait4PushButton'. The latter OPTION, requires a Push Button to be connected to a MCU pin, and for that routine to be called whenever the User wishes to see intermediate results. Adjust the Pin number if necessary in the Wait4PB code. Some Users will be able to control a Flag from the PC and avoid the need for hardware.
Just prior to calling 'Wait4PB' there needs to be a call to a Print routine such as 'Dump' (alternatively, Wait4PB could be tacked onto the end of Dump). The User needs to recognise that the Print Routines are actually programs and therefore they too use registers.
The Example Program 0 expects a Floating Point number to be pre-loaded into Register 6 before being called. In the process of creating Whole and Fraction integers for printing, it also uses Register 7. That still leaves the User with six registers in RAM and 7 more in EEPROM for Constants (not for Results - see above).
The User also needs to recognise that printing intermediate results is also subject to the Calculation being completed and therefore after Ready has been detected (a BS2 may never need to wait other than for square roots - BUT, it should be observed).
We now have this sequence for intermediate results:
ShiftOut Math Commands
PulsOut EndOfTransfer
GoSub Ready
GoSub Dump
GoSub Wait4PushButton
Where the last two steps have been added in order to display intermediate results.
Two easy to recognise problems are:
Reading the Status rather than Data:
ShiftIn Data is all zeros - the read Data is really the Status of 'Not Busy' because it never received an 'End Of Transfer' EOXfer signal and therefore never started working. Or, if it is being sent, then it is not 22us, or even as close as 19-24us.
ShiftIn Data is all ones - the Ready Status was not checked before Shifting in, and so the Status is being read, not Data.
The CoProcessor is confused:
The Program is greater than 11 bytes and the next higher number Program slot is also being used thereby causing an overlap.
The 'RunProg' is not the last Command before the end of a Stored Program, or the last Command before an EOXfer when issuing separate Commands as needed.
The fastest route is often to copy and rename an example program, then modify and test just one step at a time.
For non Parallax BS2 users, the following details should be adequate to create a robust ShiftIn and ShiftOut interface.
The Clock pulse is Active High with a min/max of 4us/14uS. The Idle Low has min/max of 10us/DontCare. Therefore the fastest repetition rate is every 4+10us or 112uS per byte which is 4+ times faster than when being driven by a BS2.
When Shifting Out, the Data Pin needs to be setup before or at the same time the Clock Pin goes high. The data cannot be updated for the next bit before the Clock goes low - at the same time is OK. Expressing in the most simple manner - the Data Pin can only be setup whilst the Clock Pin is low.
When Shifting In, the CP will drive its Data Pin approximately 2.2 uS after the leading edge of the received Clock. The recommend strobe / read time is immediately before taking the Clock Pin low. That establishes a min of 4us by the Clock specification, and serves as a good safety margin beyond the 2.2us.
If this CP is the User's first experience of FP Mathematics, one can be surprised to see not quite perfect accuracy.
Microsoft explains why right here:
The Single and Double data types are very precise — that is, they make it possible for you to specify extremely small or large numbers. However, these data types are not very accurate because they use floating-point mathematics. Floating-point mathematics has an inherent limitation in that it uses binary digits to represent decimals. Not all the numbers within the range available to the Single or Double data type can be represented exactly in binary form, so they are rounded. Also, some numbers cannot be represented exactly with any finite number of digits — pi, for example, or the decimal resulting from 1/3.
Because of these limitations to floating-point mathematics, you might encounter rounding errors when you perform operations on floating-point numbers. Compared to the size of the value you are working with, the rounding error will be very small. If you do not require absolute accuracy and can afford relatively small rounding errors, the floating-point data types are ideal for representing very small or very large values. On the other hand, if your values must be accurate — for example, if you are working with money values — you should consider one of the scaled integer data types.