FS to codec is now 1 CLKG wide; sine wave sent to codec (but still not heard)
authorRick van Rein <vanrein@hwdev.(none)>
Mon, 17 Oct 2011 14:11:28 +0000 (14:11 +0000)
committerRick van Rein <vanrein@hwdev.(none)>
Mon, 17 Oct 2011 14:11:28 +0000 (14:11 +0000)
17 files changed:
bin/i2cp/aic2x-config.c
bin/i2cp/aic2x-dump.c
bin/i2cp/aic2x-setup.c
doc/coding.rst
doc/hardware-design.rst [new file with mode: 0644]
doc/keepalive.rst [new file with mode: 0644]
doc/llc-type2.txt [new file with mode: 0644]
doc/pix/bootfloppy-i2c-busside.jpg [new file with mode: 0755]
doc/pix/bootfloppy-i2c-graycodedside.jpg [new file with mode: 0755]
doc/pix/bootfloppy-i2c-parport_pc.jpg [new file with mode: 0755]
doc/pix/bt200-twohalves.jpg [new file with mode: 0755]
doc/pix/ht162x.png [new file with mode: 0644]
doc/porting.rst
include/bottom/tic55x.h
src/driver/tic55x/grandstream-bt20x.c
src/driver/tlv320aic2x.c
src/function/develtest/echo.c

index 2cc53ab..3081c23 100644 (file)
 #define INTERPOLL_WAIT_MS 5
 
 
-const char *  regname [13] = { "1", "2", "3A", "3B", "3C", "3D", "4", "5A", "5B", "5C", "5D", "6A", "6B" };
-const uint8_t regmask [13] = { 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80 };
-const uint8_t regseln [13] = { 0x00, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80 };
+const char *  regname [14] = { "1", "2", "3A", "3B", "3C", "3D", "4A", "4B", "5A", "5B", "5C", "5D", "6A", "6B" };
+const uint8_t regmask [14] = { 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80 };
+const uint8_t regseln [14] = { 0x00, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80 };
 
-const uint8_t  regidx0 [8] = { 0, 1, 2, 6, 7,  11 };
-const uint8_t  regidx1 [8] = { 0, 1, 3, 6, 8,  12 };
-const uint8_t  regidx2 [8] = { 0, 1, 4, 6, 9,  11 };
-const uint8_t  regidx3 [8] = { 0, 1, 5, 6, 10, 12 };
+const uint8_t  regidx0 [8] = { 0, 1, 2, 6, 8,  12 };
+const uint8_t  regidx1 [8] = { 0, 1, 3, 7, 9,  13 };
+const uint8_t  regidx2 [8] = { 0, 1, 4, 6, 10, 12 };
+const uint8_t  regidx3 [8] = { 0, 1, 5, 7, 11, 13 };
 
 const uint8_t *regidxs [4] = { regidx0, regidx1, regidx2, regidx3 };
 
 int main (int argc, char *argv []) {
        int i;
-       uint8_t regs [13];
+       uint8_t regs [14];
        uint8_t slave;
 
-       if (argc != 16) {
-               fprintf (stderr, "Usage: %s /dev/i2c-N SLAVEADDR 1 2 3A 3B 3C 3D 4 5A 5B 5C 5D 6A 6B\n"
+       if (argc != 17) {
+               fprintf (stderr, "Usage: %s /dev/i2c-N SLAVEADDR 1 2 3A 3B 3C 3D 4A 4B 5A 5B 5C 5D 6A 6B\n"
                        "\tThe slave address is usually 0x40, 0x41, ... 0x4f\n"
                        "\tNumbers may be prefixed with 0 for octal, or 0x for hex\n",
                        "\tNote: All subregister indexes are assumed to be zero\n",
@@ -60,7 +60,7 @@ int main (int argc, char *argv []) {
                exit (1);
        }
 
-       for (i=0; i < 14; i++) {
+       for (i=0; i < 15; i++) {
                char *strval = argv [2+i];
                long intval;
                int base = 10;
index 2c4abcb..68a6ecd 100644 (file)
 #define INTERPOLL_WAIT_MS 5
 
 
-uint8_t regshift [7] = { 0,    8,    8,    6,    8,    6,    7    };
-uint8_t regsubs  [7] = { 0,    1,    1,    4,    1,    4,    2    };
+uint8_t regshift [7] = { 0,    8,    8,    6,    7,    6,    7    };
+uint8_t regsubs  [7] = { 0,    1,    1,    4,    2,    4,    2    };
 
 
 int main (int argc, char *argv []) {
 
-       if (argc != 2) {
-               fprintf (stderr, "Usage: %s /dev/i2c-N\n", argv [0]);
+       int minslave = 0x40;
+       int maxslave = 0x4f;
+
+       if ((argc < 2) || (argc > 3)) {
+               fprintf (stderr, "Usage: %s /dev/i2c-N [slave-address]\n", argv [0]);
                exit (1);
        }
 
+       if (argc >= 3) {
+               int base = 10;
+               char *intstr = argv [2];
+               long intval = strtol (intstr, &intstr, 0);
+               if ((*intstr) || (intval < 0x00) || (intval > 0x7f)) {
+                       fprintf (stderr, "Slave address %s is out of range\n", argv [2]);
+                       exit (1);
+               }
+               minslave = maxslave = intval;
+       }
+
        int bus = open (argv [1], O_RDWR);
        if (bus < 0) {
                perror ("Failed to open I2C bus");
@@ -54,13 +68,13 @@ int main (int argc, char *argv []) {
        ioctl (bus, I2C_TIMEOUT, 1);
        ioctl (bus, I2C_RETRIES, 2);
 
-       int chan;
-       for (chan = 0; chan <= 15; chan++) {
-               if (ioctl (bus, I2C_SLAVE, 0x40 | chan) == -1) {
-                       perror ("Failed to set channel as address");
+       int slave;
+       for (slave = minslave; slave <= maxslave; slave++) {
+               if (ioctl (bus, I2C_SLAVE, slave) == -1) {
+                       perror ("Failed to set slave address");
                        exit (1);
                }
-               printf ("Channel %d registers:", chan);
+               printf ("Channel %d registers (slave 0x%02x):", slave & 0x0f, slave);
                int reg;
                for (reg = 1; reg <= 6; reg++) {
                        uint8_t buf [6];
@@ -70,17 +84,17 @@ int main (int argc, char *argv []) {
 buf [0] =  0x01;
                                if (write (bus, buf, 1) != 1) {         // Set register number to 1
                                        perror ("Failed to setup register address");
-                                       goto nextchan; // exit (1);
+                                       goto nextslave; // exit (1);
                                }
                                usleep (INTERPOLL_WAIT_MS * 1000);
                                if (read (bus, buf + 1, 6) != 6) {              // Read current register value
                                        perror ("Failed to read register data");
-                                       goto nextchan; exit (1);
+                                       goto nextslave; exit (1);
                                }
                                printf (" %d%c=%02x", reg, "ABCD" [(buf [reg] >> regshift [reg])], buf [reg]);
                        }
                }
-nextchan:
+nextslave:
                printf ("\n");
        }
 
index 3abdcd0..c9dce36 100644 (file)
@@ -44,9 +44,9 @@
 #define INTERPOLL_WAIT_MS 5
 
 
-const char *  regname [13] = { "1", "2", "3A", "3B", "3C", "3D", "4", "5A", "5B", "5C", "5D", "6A", "6B" };
-const uint8_t regmask [13] = { 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80 };
-const uint8_t regseln [13] = { 0x00, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80 };
+const char *  regname [14] = { "1", "2", "3A", "3B", "3C", "3D", "4A", "4B", "5A", "5B", "5C", "5D", "6A", "6B" };
+const uint8_t regmask [14] = { 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80 };
+const uint8_t regseln [14] = { 0x00, 0x00, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80, 0x00, 0x40, 0x80, 0xc0, 0x00, 0x80 };
 
 uint8_t argval (char *strval) {
        long intval;
@@ -74,7 +74,7 @@ int main (int argc, char *argv []) {
        uint8_t slave;
 
        if (argc < 4) {
-               fprintf (stderr, "Usage: %s /dev/i2c-N SLAVEADDR REGISTER=VALUE\n"
+               fprintf (stderr, "Usage: %s /dev/i2c-N SLAVEADDR REGISTER=VALUE...\n"
                        "\tThe slave address is usually 0x40, 0x41, ... 0x4f\n"
                        "\tThe register may be a subregister, the value is a number\n"
                        "\tNumbers may be prefixed with 0 for octal, or 0x for hex\n"
index 2dff7d2..040316f 100644 (file)
@@ -151,6 +151,13 @@ is interesting; if the ``textptr_t`` is removed, nobody will miss it
 because the actual string is not stored explicitly.  A null string
 would contain a NULL pointer reference to the first character.
 
+This approach will make it straightforwardly possible to embed a
+string inside other structures, or possibly even allocate it on
+the stack for the duration of an operation.  The scoping of stacks
+very often coincides with the scope during which a string or other
+piece of data is needed.  Not having to clean up a ``textptr_t``
+makes it eminently suitable for such implicit lifetime management.
+
 A few macros/functions exist to make life easier while working with
 these simple strings.  They are defined in include file ``<0cpm/text.h>``
 to do the following:
@@ -179,5 +186,8 @@ not half bad, but double bad).  At times, this will mean writing a lot of
 code and testing it all at once.  Still, its structure will help you to
 find the problem spot more easily.
 
-Just don't forget to increment your counters...
+Just don't forget to increment your loop counters...  although always somewhat
+embarrassing, it is very common to forget it, and be faced with a total freeze,
+because the 0cpm Firmerware has a single thread of control.  And it is not
+always easy to find the place where this happens.
 
diff --git a/doc/hardware-design.rst b/doc/hardware-design.rst
new file mode 100644 (file)
index 0000000..6e36048
--- /dev/null
@@ -0,0 +1,268 @@
+Hints on Phone Hardware Design
+==============================
+
+This document provides a number of hints regarding the design of phone hardware.
+As phones are always on, a main concern below is saving energy.
+
+The 0cpm Firmerware has been designed specifically to take advantage of the
+following hardware facilities.
+
+
+Display
+-------
+
+It is not common for phones to employ a bistable display, but it makes a lot of sense
+to use them.  An LCD display usually needs a backlight, causing them to glow rather
+loudly in the evening, and be hard to read at daytime, unless the backlight is constantly
+active.  Bistable displays usually have excellent contrast, and will reflect ambient
+light in much the same way as paper; this is why such displays are sometimes referred
+to as e-paper.
+
+Aside from the backlight, an LCD driver also sends constantly changing signals to the
+LCD, and that too can be improved upon.
+
+
+Keys / buttons
+--------------
+
+They keyboard of a phone is usually a matrix.  It is simpler than a PC keyboard, in that
+no phones seem to rely on pressing more than one key at the same time.
+
+Traditionally, keyboards were scanned at regular intervals.  This however, means that
+the processor must be active very often, and may not be able to sleep as deeply as it
+could otherwise.  Given that (a) phone keys are rarely used, and (b) the keys should
+be responded to quickly, it is better to ensure that the keys raise an interrupt on
+the target CPU.  This may take a bit more hardware than usual, but it should save in
+the total power budget.
+
+Note that a matrix allows selection of all input columns at the same time; any key
+pressed would then immediately show up as an activated row.  Once that signal has
+arrived, the columns can be scanned to find the actual key being pressed.  Depending
+on the CPU, even the release of the key may be picked up on as an interrupt, or it
+may require scanning while the keyboard is active.
+
+
+Hook contact
+------------
+
+The hook contact is usually connected to a GPIO port.  Make sure it can trigger an
+interrupt, both when pickup up and putting down the horn.  The reason is the same as
+for the keyboard matrix, with which it usually is not integrated.
+
+
+Sound DMA
+---------
+
+The codec that exchanges sound with the user is best operated under DMA, so as to
+make the rate at which samples are exchanged highly constant.  Without DMA, the
+timing would have to rely on something like interrupts; but interrupts may get
+delayed by other interrupts and critical sections.  DMA should cut through
+everything in a very resource-friendly manner.
+
+
+Sleep mode
+----------
+
+If a CPU or DSP or SoC has a low-power mode, design for it.  Phones are rarely used,
+but must always be on.  While setting up a call, the CPU can speed up its clock and
+wake up peripherals for the duration of a call.  If the voltages of the CPU can be
+lower in its inactive mode, chances are that even more power is saved.  This is a
+common phenomenon in processors, memories and more chips.  Design for it and win
+the beauty contest of the lowest-energy phone!
+
+
+Network switching
+-----------------
+
+A phone often has two connectors on its back side; one is the uplinnk the the LAN, the
+other is the downlink to a PC.  The 0cpm Firmerware assumes that the ports are marked
+accordingly.
+
+Inasfar as PC traffic travels through the phone to the uplink, it should be switched at
+the lowest possible level of the network stack.  Usually, this means Ethernet switching.
+If it is implemented in a hardware switch, the little CPU in the phone can never become
+the bottle neck for networking; also, it does not have to spend time, wake up, and so on.
+
+**Looking ahead:**
+Ideally, but not commonly, a switch could connect the PC to the uplink at the physical
+layer, by connecting the wires of the two ports.  It would however also observe what
+travels over the wires, and be able to take them apart and sit in between as a switch.
+It would do the latter to respond to Ethernet traffic directed at its MAC address and
+when operating as a phone.  As was said, this is not common practice, but it would make
+sense for a wide variety of embedded applications that only send very rarely, and in
+determined bursts.  That includes phones, measuring equipment, and probably many more
+small devices.
+
+
+Tickless RTOS
+-------------
+
+The heart of the 0cpm Firmerware is essentially a tickless RTOS.  It will not do
+anything until an event occurs -- where events could be picking up or putting down
+the horn, operating a button, or receiving a network packet.  There should be no
+other reason for a phone to wake up.  (Although one can never fully predict what
+applications people will want to run on their phones -- they might be used for
+surveying a room by sampling the sound level, for instance.)
+
+The RTOS is split in a top half (with generic code) and a bottom half (with drivers).
+Needless to say, a tickless RTOS will only work well on drivers that support the
+tickless behaviour.  So the aforementioned advantages in hardware must be built
+into the drivers, and the proper configuration flags should also be applied.
+
+
+Differentiate with extravagant hardware
+---------------------------------------
+
+SIP phones can do much more than just telephony, and the 0cpm Firmerware exists to
+make just that happen.  You could consider an alarm clock, a door bell (with camera)
+for one home or a building block for appartment blocks that can be forwarded or
+voicemailed like any other phone; but there are other variations that can be made
+true with simple extensions -- and you might not always be able to foresee them.
+In short, it pays to be different, and add extras.
+
+**PS/2.** A simple externalised UART port could do fun things.  Imagine hooking up
+a keyboard to enable realtime text (RTT) between users.  This is an RTP-protocol
+that is much loved by people with hearing impairments, because it enables them to
+interrupt each other, something they cannot do with plain chat.  Needless to say
+that devices in support of disabled users also benefit regular users.  It is an
+incredible benefit from what is a trivial extension in terms of hardware.  The
+interesting thing of adding a feature like RTT to an open source application also
+implies that other devices, from other manufacturers, can be updated with your
+application code, so your application can be adopted much faster than with a
+product that only your company markets.
+
+**HiFi sound.** Many office workers enjoy music in their work place.  Using a codec
+with high quality speaker outputs may not only save you the cost of integrating a
+speaker in the phone, it also creates possibilities for webradio support.  But do
+keep in mind that most phone calls use a sampling rate in the audible region -- so
+your codec must be able to either oversample and filter away anti-aliasing aspects
+in the sound -- or your user will be very tense from high tone disturbance.
+
+**Stereo sound.** Whether HiFi or not, stereo sound is useful for telephony, and the
+protocols support it.  The utility of stereo sound would be that contacts could be
+positioned in a semicircle surrounding the caller, so the voices are much simpler
+for a user to separate.  This facility could be implemented in a meeting room service
+or in the phone itself -- by combining incoming mono voice channels.  As before, this
+code would be general 0cpm Firmerware code, and would thus be made available to other
+devices as well.  This means that those devices can pick up on stereo telephony
+faster than if it was limited to a closed system.
+
+Stereo sound can also be surprisingly useful for microphones.  If you have never
+experienced being blind, you might try dining in absolute darkess (asking a real
+blind person to serve you in avoidance of a mess).  It is a striking sensation to
+notice that you immediately feel if someone is talking directly to you.  Imagine
+the value of having that in a phone conversation!
+
+**Be extravagant.** The big lesson seems to be that support for disabled or specialised
+users is not a burden, it can actually be an inspiration.  Even if you don't see a
+useful application, you can be fairly certain that the open source community will.
+Just ship a few of your phones to active developers and see what will happen... it's
+the cheapest marketing possible!
+
+
+Open, open, open
+----------------
+
+The openness of the 0cpm Firmerware is not a danger, it is a feature that will
+save you lots of work.  Development cycles can shorten dramatically, and the
+World is full of potential programmers that may pickup where you left.  By
+pointing to an open source community, you can actually tell people to some
+extent to help themselves when it comes to support and repair.
+
+To gain these qualities, all you need to do is open your changes to the code.
+This is not just a legal requirement of using the 0cpm Firmerware, but it is
+also necessary to allow people to help themselves.  That means that any driver
+code that you develop in-house for your target chip must also be open.
+
+There are a few checks that you should make before choosing a hardware platform
+for the 0cpm Firmerware:
+
+* You must use a freely distributable toolchain.  A lot of platforms are supported
+  by ``gcc`` and ``binutils``, including quite a few embedded environments.  In  more
+  and more cases, the platform vendor will have embraced open source support for the
+  same reasons you are now considering it for your phone.  Choose another platform
+  if this check fails.
+
+* You can only use libraries that are compatible with GPL.  Using libraries that
+  may not be redistributed or linked to GPL code and/or that come without source code 
+  make it impossible for you to open up your application.  Choose another platform
+  if this check fails, or decide to write the basic drivers yourself, and add them
+  to the bottom half of the 0cpm Firmerware.
+
+* You should not base your work on limited-access documentation.  The lack of
+  documentation severely limits future developers to make any contributions
+  that are specifically lucrative on your platform.  You may want to choose
+  another platform if this check fails.
+
+* You must make it possible for end users to replace the firmware on your device
+  with any version that they may have created themselves, or found somewhere
+  online.  Obviously, you are not required to support a product with third-party
+  firmware.  But you should probably provide a bootloader (like the generic one
+  provided as part of the 0cpm Firmerware) or other mechanism to permit an
+  upgrade of the firmware.  As a general rule, you should make it as easy for
+  end users as it is for you
+  to develop for the device, and upload firmware to it.  This implies that you
+  must not use digital signatures to ban uploads of firmware that were not
+  authorised by you.  Checksums and hashes to validate the contents of an
+  image before burning it into Flash memory are a different story; they are a
+  good precaution; be sure to document such platform-specifics though, for
+  example by including it in the build chain for the firmware.
+
+  If you incorporate the bootloader of the 0cpm Firmerware then you should also
+  enable end-users to replace that part of Flash (as a separate module), but
+  if you use a closed bootloader then you need not support its replacement.  The generic
+  bootloader in the 0cpm Firmerware can be used to upload to independent flash partitions,
+  and the same mechanism can also be used to upload other things, like ringtone
+  files.
+
+* Your management should underwrite the opening up of any changes that you
+  make to the 0cpm Firmerware; if they question this, you can
+  explain that they will save lots of money on development and support
+  by incorporating lots of existing code and that only a little bit has to be
+  added and opened to the World.  In case your manager argues that this makes
+  the code available to competitors, explain that the competitor can already
+  choose to download complete code for other platforms, and that the essence
+  of the advantage is that adding less value in the form of firmware means
+  that less protection can be gained from it -- but that the essence of being
+  in electronics is not to create and support firmware, but rather to produce hardware.
+  And when it comes to making money from a total solution, it is hardware that
+  feels an asset to buyers, not firmware.  Be very clear to your managers -- they
+  should understand that pulling out of intended openness after porting the
+  0cpm Firmerware would make it illegal to sell the product at all -- and that
+  there are volunteers who care enough about these things to prosecute
+  companies that invalidate open source licenses.
+
+* As soon as your port is working, write a document in the ``doc/bottom/``
+  directory.  You can clone ``SKELETON.rst`` as a starting point.  Please
+  create a directory with your manufacturing domainname and place your
+  documents in there.  The document should explain the following things to
+  developer-type end users:
+
+  - Whether they loose their warrenty if they upload their own firmware;
+  - What hardware is used for the product they bought;
+  - If you feel so inclined, a schematic circuit of the hardware;
+  - Where to find the source code (possibly at the 0cpm project itself);
+  - Where to find the toolchain that you used to develop the firmware;
+  - How you built the firmware for the device (cmdline instructions);
+  - Whether debugging interfaces exists, and how to use them;
+  - Possibly how to retrieve the current firmware from your device;
+  - How to upload newly built firmware to your device;
+  - Possibly how to recover if a firmware version fails.
+
+  The ``SKELETON.rst`` file gives examples for each, and you are welcome to
+  reuse it to construct this documentation, with or without modification.
+  Please retain the ``.rst`` extension and follow the Docutils_ guidelines
+  when documenting, and test with a tool like ``doc2html`` whether it is free
+  of errors.  You will find that Docutils is a very useful tool for writing
+  documentation efficiently for a variety of output formats.
+
+  .. _Docutils : http://docutils.sourceforge.net/rst.html
+
+Please keep in mind that the requirements of openness exist to keep the
+0cpm Firmerware open at all times.  This is beneficial for your end users,
+and will reflect upon the popularity of your hardware.  Even if you have to
+select a different platform from a closed one with a lower per-unit cost, it
+will still save you lots in development and support, and make your hardware
+more popular and longer-lasting; so, as a result the open platform is likely
+to be a financially better alternative due to more than the per-unit cost.
+
diff --git a/doc/keepalive.rst b/doc/keepalive.rst
new file mode 100644 (file)
index 0000000..d9e45d0
--- /dev/null
@@ -0,0 +1,120 @@
+The Keepalive mechanism in 0cpm Firmerware
+==========================================
+
+Phones need to be open to incoming calls, possibly hours
+after they have registered over an UDP port.  In most
+networks, the fact that UDP has gone from the inside out
+is forgotten long before that call comes in.  So, there
+is a need for some form of keepalive.
+
+
+What should be kept open?
+-------------------------
+
+If the LAN is a retro network, offering only IPv4, the
+phone uses 6bed4 as a last resort to IPv6 connectivity.
+In these cases, the phone usually has to pierce through
+(at least) one layer of NAT, but except for NAT and
+firewalls at the IPv4 layer, it is not to be expected
+that the embedded IPv6 traffic requires any keepalive
+functionality.
+
+If the LAN supports IPv6, then it is probable that there
+is a firewall (or multiple) in the path to the outside
+world.  This means that state is probably kept and in
+lieu of that for UDP, that holes opened by outgoing
+UDP traffic would be dropped.  So, for IPv6 it is also
+needed to keep those holes open.
+
+
+A few stupid approaches
+-----------------------
+
+The brute force approach to keep connections open at all
+times is to send a regular packet to the SIP server,
+possibly without any data contained after the UDP header.
+Given that some NATs are very quick to forget holes due
+to outgoing traffic, that would have to be done once per
+30 seconds.
+
+This would be end-to-end and extremely often, so the burden
+on the network would be maximal, and could actually be
+pretty big if the number of phones doing that would be
+huge.  Given that this is open source firmware, it has
+an enormous potential to grow rapidly, so it is better
+to reduce the network load by limiting the number of
+hops to just get outside NAT and/or firewalls, and by
+making the repeating period longer.  As long as it is
+autodetected, this should be no problem to users.
+
+
+Autodetecting the repeating period
+----------------------------------
+
+To find the shortest working repeat period, we will try
+a value just under 30 seconds and double for as long as
+it works.  Starting at 28 seconds, doubling it several
+times gets to a value of 3584 seconds or just under an
+hour, which is the most likely value to work.  It does
+not seem to waste much time of the 3600 seconds that
+are expected to be very common in NAT and firewalls.
+
+The system will maintain a safe setting for the actual
+connection for the data, and experiment on the side
+with an extra connection that exists just for that
+purpose.  While keeping the safe connection alive, the
+test connection can be skipped once in every two
+keepalive tests.  If a few such tests lead to proper
+behaviour, the safe setting can be doubled, and the
+process can repeat.  Of course there is no sense in
+testing on the keepalive process when its interval
+has exceeded the SIP registration interval.
+
+
+Autodetecting the hop limit
+---------------------------
+
+To avoid bothering more routers and servers than
+strictly required, a lower hop limit on the keepalive
+packets helps.  In the case of native IPv6, this
+would be the IPv6 hop limit; in the case of the 6bed4
+fallback, the Time To Live in the underlying IPv4 packet 
+would be used.
+
+Not all firewalls can be detected by way of their
+changing of an IPv4 address, especially not IPv6
+firewalls.  So, it will not be sufficient to detect
+when a global IP address is assigned.  Instead, the
+autodetection of the hop limit must be based on
+actual communication through the outside world.
+
+The simplest approach is to start with a zero hop
+limit, and increment it until it is possible to
+receive external communications.  Once that works,
+it is clear that all intermediate firewalls have
+had a hole punched in them.
+
+TODO: EXTERNAL-ACCESS-HOW?
+
+
+
+Combining the autodetection algorithms
+--------------------------------------
+
+The two autodetection mechanisms could be combined
+in a number of orders.  The best approach is probably
+to start from an impossibly short hop limit, incrementing
+it until success, and then to migrate the detection of
+the longest possible keepalive repeat period to a
+background process.  That way, it is possible to quickly
+fire up a working service, while still putting a modest
+and local footprint on the network; period autodetection
+needs time and can then be done quietly in the background,
+without any danger of overloading anything.
+
+Given the modesty after hop limit detection alone, it
+could be argued that there need not be any further work
+done.  But why not go for the ultimate, especially if
+on some networks it would save all the work?
+
+
diff --git a/doc/llc-type2.txt b/doc/llc-type2.txt
new file mode 100644 (file)
index 0000000..2ae9c3b
--- /dev/null
@@ -0,0 +1,296 @@
+No.     Time        Source                Destination           Protocol Info
+      1 0.000000    Msi_ee:8f:a9          Compulab_04:48:87     LLC      U P, func=SABME; DSAP 0x16 Individual, SSAP 0x16 Command
+
+Frame 1 (17 bytes on wire, 17 bytes captured)
+    Arrival Time: May  2, 2011 09:24:38.998136000
+    [Time delta from previous captured frame: 0.000000000 seconds]
+    [Time delta from previous displayed frame: 0.000000000 seconds]
+    [Time since reference or first frame: 0.000000000 seconds]
+    Frame Number: 1
+    Frame Length: 17 bytes
+    Capture Length: 17 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 3
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Command
+    Control field: U P, func=SABME (0x7F)
+        ...1 .... = Poll: Set
+        011. 11.. = Command: Set Asynchronous Balanced Mode Extended (0x1b)
+        .... ..11 = Frame type: Unnumbered frame (0x03)
+
+0000  00 01 c0 04 48 87 00 16 17 ee 8f a9 00 03 16 16   ....H...........
+0010  7f                                                .
+\fNo.     Time        Source                Destination           Protocol Info
+      2 0.000284    Compulab_04:48:87     Msi_ee:8f:a9          LLC      U F, func=UA; DSAP 0x16 Individual, SSAP 0x16 Response
+
+Frame 2 (60 bytes on wire, 60 bytes captured)
+    Arrival Time: May  2, 2011 09:24:38.998420000
+    [Time delta from previous captured frame: 0.000284000 seconds]
+    [Time delta from previous displayed frame: 0.000284000 seconds]
+    [Time since reference or first frame: 0.000284000 seconds]
+    Frame Number: 2
+    Frame Length: 60 bytes
+    Capture Length: 60 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 3
+    Trailer: 000000000000000000000000000000000000000000000000...
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Response
+    Control field: U F, func=UA (0x73)
+        ...1 .... = Final: Set
+        011. 00.. = Response: Unnumbered Acknowledge (0x18)
+        .... ..11 = Frame type: Unnumbered frame (0x03)
+
+0000  00 16 17 ee 8f a9 00 01 c0 04 48 87 00 03 16 17   ..........H.....
+0010  73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   s...............
+0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+0030  00 00 00 00 00 00 00 00 00 00 00 00               ............
+\fNo.     Time        Source                Destination           Protocol Info
+      3 3.858532    Msi_ee:8f:a9          Compulab_04:48:87     LLC      I, N(R)=0, N(S)=0; DSAP 0x16 Individual, SSAP 0x16 Command
+
+Frame 3 (24 bytes on wire, 24 bytes captured)
+    Arrival Time: May  2, 2011 09:24:42.856668000
+    [Time delta from previous captured frame: 3.858248000 seconds]
+    [Time delta from previous displayed frame: 3.858248000 seconds]
+    [Time since reference or first frame: 3.858532000 seconds]
+    Frame Number: 3
+    Frame Length: 24 bytes
+    Capture Length: 24 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc:data]
+IEEE 802.3 Ethernet 
+    Destination: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 10
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Command
+    Control field: I, N(R)=0, N(S)=0 (0x0000)
+        0000 000. .... .... = N(R): 0
+        .... .... 0000 000. = N(S): 0
+        .... .... .... ...0 = Frame type: Information frame (0x0000)
+Data (6 bytes)
+    Data: 68616C6C6F0A
+
+0000  00 01 c0 04 48 87 00 16 17 ee 8f a9 00 0a 16 16   ....H...........
+0010  00 00 68 61 6c 6c 6f 0a                           ..hallo.
+\fNo.     Time        Source                Destination           Protocol Info
+      4 3.858857    Compulab_04:48:87     Msi_ee:8f:a9          LLC      S, func=RR, N(R)=1; DSAP 0x16 Individual, SSAP 0x16 Response
+
+Frame 4 (60 bytes on wire, 60 bytes captured)
+    Arrival Time: May  2, 2011 09:24:42.856993000
+    [Time delta from previous captured frame: 0.000325000 seconds]
+    [Time delta from previous displayed frame: 0.000325000 seconds]
+    [Time since reference or first frame: 3.858857000 seconds]
+    Frame Number: 4
+    Frame Length: 60 bytes
+    Capture Length: 60 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 4
+    Trailer: 000000000000000000000000000000000000000000000000...
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Response
+    Control field: S, func=RR, N(R)=1 (0x0201)
+        0000 001. .... .... = N(R): 1
+        .... .... .... 00.. = Supervisory frame type: Receiver ready (0x0000)
+        .... .... .... ..01 = Frame type: Supervisory frame (0x0001)
+
+0000  00 16 17 ee 8f a9 00 01 c0 04 48 87 00 04 16 17   ..........H.....
+0010  01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+0030  00 00 00 00 00 00 00 00 00 00 00 00               ............
+\fNo.     Time        Source                Destination           Protocol Info
+      5 6.299565    Compulab_04:48:87     Msi_ee:8f:a9          LLC      I, N(R)=1, N(S)=0; DSAP 0x16 Individual, SSAP 0x16 Command
+
+Frame 5 (60 bytes on wire, 60 bytes captured)
+    Arrival Time: May  2, 2011 09:24:45.297701000
+    [Time delta from previous captured frame: 2.440708000 seconds]
+    [Time delta from previous displayed frame: 2.440708000 seconds]
+    [Time since reference or first frame: 6.299565000 seconds]
+    Frame Number: 5
+    Frame Length: 60 bytes
+    Capture Length: 60 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc:data]
+IEEE 802.3 Ethernet 
+    Destination: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 8
+    Trailer: 000000000000000000000000000000000000000000000000...
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Command
+    Control field: I, N(R)=1, N(S)=0 (0x0200)
+        0000 001. .... .... = N(R): 1
+        .... .... 0000 000. = N(S): 0
+        .... .... .... ...0 = Frame type: Information frame (0x0000)
+Data (4 bytes)
+    Data: 686F690A
+
+0000  00 16 17 ee 8f a9 00 01 c0 04 48 87 00 08 16 16   ..........H.....
+0010  00 02 68 6f 69 0a 00 00 00 00 00 00 00 00 00 00   ..hoi...........
+0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+0030  00 00 00 00 00 00 00 00 00 00 00 00               ............
+\fNo.     Time        Source                Destination           Protocol Info
+      6 6.299586    Msi_ee:8f:a9          Compulab_04:48:87     LLC      S, func=RR, N(R)=1; DSAP 0x16 Individual, SSAP 0x16 Response
+
+Frame 6 (18 bytes on wire, 18 bytes captured)
+    Arrival Time: May  2, 2011 09:24:45.297722000
+    [Time delta from previous captured frame: 0.000021000 seconds]
+    [Time delta from previous displayed frame: 0.000021000 seconds]
+    [Time since reference or first frame: 6.299586000 seconds]
+    Frame Number: 6
+    Frame Length: 18 bytes
+    Capture Length: 18 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 4
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Response
+    Control field: S, func=RR, N(R)=1 (0x0201)
+        0000 001. .... .... = N(R): 1
+        .... .... .... 00.. = Supervisory frame type: Receiver ready (0x0000)
+        .... .... .... ..01 = Frame type: Supervisory frame (0x0001)
+
+0000  00 01 c0 04 48 87 00 16 17 ee 8f a9 00 04 16 17   ....H...........
+0010  01 02                                             ..
+\fNo.     Time        Source                Destination           Protocol Info
+      7 7.487863    Compulab_04:48:87     Msi_ee:8f:a9          LLC      U P, func=DISC; DSAP 0x16 Individual, SSAP 0x16 Command
+
+Frame 7 (60 bytes on wire, 60 bytes captured)
+    Arrival Time: May  2, 2011 09:24:46.485999000
+    [Time delta from previous captured frame: 1.188277000 seconds]
+    [Time delta from previous displayed frame: 1.188277000 seconds]
+    [Time since reference or first frame: 7.487863000 seconds]
+    Frame Number: 7
+    Frame Length: 60 bytes
+    Capture Length: 60 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 3
+    Trailer: 000000000000000000000000000000000000000000000000...
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Command
+    Control field: U P, func=DISC (0x53)
+        ...1 .... = Poll: Set
+        010. 00.. = Command: Disconnect (0x10)
+        .... ..11 = Frame type: Unnumbered frame (0x03)
+
+0000  00 16 17 ee 8f a9 00 01 c0 04 48 87 00 03 16 16   ..........H.....
+0010  53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   S...............
+0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+0030  00 00 00 00 00 00 00 00 00 00 00 00               ............
+\fNo.     Time        Source                Destination           Protocol Info
+      8 7.487888    Msi_ee:8f:a9          Compulab_04:48:87     LLC      U F, func=UA; DSAP 0x16 Individual, SSAP 0x16 Response
+
+Frame 8 (17 bytes on wire, 17 bytes captured)
+    Arrival Time: May  2, 2011 09:24:46.486024000
+    [Time delta from previous captured frame: 0.000025000 seconds]
+    [Time delta from previous displayed frame: 0.000025000 seconds]
+    [Time since reference or first frame: 7.487888000 seconds]
+    Frame Number: 8
+    Frame Length: 17 bytes
+    Capture Length: 17 bytes
+    [Frame is marked: False]
+    [Protocols in frame: eth:llc]
+IEEE 802.3 Ethernet 
+    Destination: Compulab_04:48:87 (00:01:c0:04:48:87)
+        Address: Compulab_04:48:87 (00:01:c0:04:48:87)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Source: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        Address: Msi_ee:8f:a9 (00:16:17:ee:8f:a9)
+        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
+        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
+    Length: 3
+Logical-Link Control
+    DSAP: Unknown (0x16)
+    IG Bit: Individual
+    SSAP: Unknown (0x16)
+    CR Bit: Response
+    Control field: U F, func=UA (0x73)
+        ...1 .... = Final: Set
+        011. 00.. = Response: Unnumbered Acknowledge (0x18)
+        .... ..11 = Frame type: Unnumbered frame (0x03)
+
+0000  00 01 c0 04 48 87 00 16 17 ee 8f a9 00 03 16 17   ....H...........
+0010  73                                                s
diff --git a/doc/pix/bootfloppy-i2c-busside.jpg b/doc/pix/bootfloppy-i2c-busside.jpg
new file mode 100755 (executable)
index 0000000..e6e3b32
Binary files /dev/null and b/doc/pix/bootfloppy-i2c-busside.jpg differ
diff --git a/doc/pix/bootfloppy-i2c-graycodedside.jpg b/doc/pix/bootfloppy-i2c-graycodedside.jpg
new file mode 100755 (executable)
index 0000000..75bb428
Binary files /dev/null and b/doc/pix/bootfloppy-i2c-graycodedside.jpg differ
diff --git a/doc/pix/bootfloppy-i2c-parport_pc.jpg b/doc/pix/bootfloppy-i2c-parport_pc.jpg
new file mode 100755 (executable)
index 0000000..0d8d468
Binary files /dev/null and b/doc/pix/bootfloppy-i2c-parport_pc.jpg differ
diff --git a/doc/pix/bt200-twohalves.jpg b/doc/pix/bt200-twohalves.jpg
new file mode 100755 (executable)
index 0000000..323e871
Binary files /dev/null and b/doc/pix/bt200-twohalves.jpg differ
diff --git a/doc/pix/ht162x.png b/doc/pix/ht162x.png
new file mode 100644 (file)
index 0000000..b9366e3
Binary files /dev/null and b/doc/pix/ht162x.png differ
index 762068b..9084cdf 100644 (file)
@@ -97,6 +97,7 @@ on hand:
 * glass scraper with a handle
 * soldering iron and related tools
 * wires, jumpers, access to all sorts of electronics parts
+* a thin, sharp and stiff sewing needle
 * Linux PC (Windows might work as a sub-optimal substitute)
 * useful if available: oscilloscope, logic analyser
 
@@ -134,9 +135,9 @@ In fixating on the pin, you can easily apply too much force, causing
 the pin to split apart and cover a bit more area.  With the small sizes
 of surface mount technology, this may lead to a short-circuit with
 the neighbouring pins!  Most circuitry will even survive such a harsh
-treatment, and you can resolve it by taking a needle (not a sewing pin,
-as those will bend) and scratching carefully between the pins that got
-connected.  A strong sign of such unwanted connectivity is if the
+treatment, and you can resolve it by taking a **sewing needle** (not a
+pin, as those will bend) and scratching carefully between the pins that
+got connected.  A strong sign of such unwanted connectivity is if the
 original firmware starts to behave strangely and it appears as though
 you destroyed a piece of its hardware.  Still, it will take quite a bit
 of your intuition and ingenuity to determine the error spot, but on the
index 64b141e..bca0f8a 100644 (file)
@@ -283,9 +283,11 @@ asm ("_DRR1_1 .set 0x2c00");
 #define REGVAL_SPCR1_RRST_NOTRESET     0x0001
 #define REGVAL_SPCR2_FRST_NOTRESET     0x0080
 #define REGVAL_SPCR2_GRST_NOTRESET     0x0040
+#define REGVAL_SPCR2_XRDY              0x0002
 #define REGVAL_SPCR2_XRST_NOTRESET     0x0001
 
-#define REGVAL_SRGR1_FWID_1            0x0100
+#define REGVAL_SRGR1_FWID_1            0x0000
+#define REGVAL_SRGR1_FWID_2            0x0100
 #define REGVAL_SRGR1_CLKGDIV_1         0x0001
 #define REGVAL_SRGR1_CLKGDIV_4         0x0004
 #define REGVAL_SRGR1_CLKGDIV_5         0x0005
index f01b8c8..5103bf6 100644 (file)
@@ -261,7 +261,8 @@ int16_t codec_decode (codec_t codec, uint8_t *in, uint16_t inlen, uint16_t *out,
                register uint8_t inval = *in++;
                switch (codec) {
                case CODEC_L8:
-                       *out++ = (inval ^ 0x80) << 8;
+                       //TODO// *out++ = (inval ^ 0x80) << 8;
+*out++ = 16384 + 1 + (outlen & 0x01)? 0: 32768;
                        break;
                case CODEC_L16:
                        *out++ = inval;
@@ -356,6 +357,7 @@ int16_t codec_encode (codec_t codec, uint16_t *in, uint16_t inlen, uint8_t *out,
 
 /* Set a frequency divisor for the intended sample rate */
 void tlv320aic2x_set_samplerate (uint32_t samplerate) {
+int chan = 0;
 #ifndef TODO_FS_ONLY_DURING_SOUND_IO
        SPCR2_1 &= ~ ( REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET );
 #endif
@@ -366,6 +368,8 @@ void tlv320aic2x_set_samplerate (uint32_t samplerate) {
                samplerate = 1;
        }
        SRGR2_1 = REGVAL_SRGR2_CLKSM | REGVAL_SRGR2_FSGM | (samplerate - 1);
+//TODO// tlv320aic2x_setreg (chan, 4, 0x00 | ((6 & 0x0f) << 3) | (2 & 0x07));  // N:=6, P:=2
+//TODO// tlv320aic2x_setreg (chan, 4, 0x80 | (16 & 0x7f));                     // M:=16
 #ifndef TODO_FS_ONLY_DURING_SOUND_IO
        SPCR2_1 |= REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET;
        SPCR1_1 |= REGVAL_SPCR1_RRST_NOTRESET;
@@ -391,6 +395,8 @@ interrupt void tic55x_dmac0_isr (void) {
        uint16_t irq = DMACSR_0;        // Note causes and clear
        tic55x_top_has_been_interrupted = true;
        if ((available_record += 64) > (BUFSZ - 64)) {
+               SPCR2_1 &= ~REGVAL_SPCR2_XRST_NOTRESET;
+               SPCR2_1 |=  REGVAL_SPCR2_XRST_NOTRESET;
                DMACCR_0 &= ~REGVAL_DMACCR_EN;
 #ifdef TODO_FS_ONLY_DURING_SOUND_IO
                SPCR1_1 &= ~REGVAL_SPCR1_RRST_NOTRESET;
@@ -418,7 +424,6 @@ interrupt void tic55x_dmac1_isr (void) {
                        SPCR2_1 &= ~ (REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET);
                }
 #endif
-               DXR1_1 = DXR1_1;        // Flag down XEMPTY
                DMACCR_1 &= ~REGVAL_DMACCR_EN;
        }
        toplay = BUFSZ - available_play;
@@ -452,6 +457,7 @@ void dmahint_record (void) {
  */
 void dmahint_play (void) {
        if ((available_play >= 64) && ! (DMACCR_1 & REGVAL_DMACCR_EN)) {
+               DXR1_1 = DXR1_1;        // Flag down XEMPTY
                DMACCR_1 |= REGVAL_DMACCR_EN;
 bottom_printf ("dmahint_play() started playing DMA\n");
 #ifdef TODO_FS_ONLY_DURING_SOUND_IO
@@ -999,8 +1005,12 @@ void main (void) {
        SPCR2_1 = 0x0000;       // Disable/reset sample rate generator
        SRGR1_1 = REGVAL_SRGR1_FWID_1 | REGVAL_SRGR1_CLKGDIV_4;
        SRGR2_1 = REGVAL_SRGR2_CLKSM | REGVAL_SRGR2_FSGM | REGVAL_SRGR2_FPER_1535;
-       PCR1 = /*TODO: (1 << REGBIT_PCR_IDLEEN) | */ (1 << REGBIT_PCR_FSXM) | (1 << REGBIT_PCR_FSRM) | (1 << REGBIT_PCR_CLKXM) | (1 << REGBIT_PCR_CLKRM) /* TODO:WRONG? | (1 << REGBIT_PCR_CLKXP) | (1 << REGBIT_PCR_CLKRP) */;
-       SPCR1_1 |= REGVAL_SPCR1_CLKSTP_NODELAY;
+       PCR1 = /*TODO: (1 << REGBIT_PCR_IDLEEN) | */ (1 << REGBIT_PCR_FSXM) /* | (1 << REGBIT_PCR_FSRM) */ | (1 << REGBIT_PCR_CLKXM) /* | (1 << REGBIT_PCR_CLKRM) */ /* receive on falling, xmit on rising edge -- | (1 << REGBIT_PCR_CLKXP) | (1 << REGBIT_PCR_CLKRP) */;
+       RCR1_1 = (0 << 8) | (2 << 5);   // Read  1 frame of 16 bits per FS
+       XCR1_1 = (0 << 8) | (2 << 5);   // Write 1 frame of 16 bits per FS
+       RCR2_1 = 0x0001;                // Read  with 1 clockcycle delay
+       XCR2_1 = 0x0001;                // Write with 1 clockcycle delay
+       //TODO:NOT-SPI-BUT-CONTINUOUS-CLOCK// SPCR1_1 |= REGVAL_SPCR1_CLKSTP_NODELAY;
        //
        // Setup I2C for communication with the TLV320AIC20K codec
        // Prescale SYSCLK2 down from 61.44 MHz to 10.24 MHz so it falls
index 0d81e6d..e437926 100644 (file)
@@ -275,7 +275,9 @@ void tlv320aic2x_setup_sound (void) {
                tlv320aic2x_setreg (chan, 3, 0x40 | 0x20);      /* Setup 8 kHz filter, no mute */
                /* Register 3C resets ok to 0x80 | (chip_id << 2) */
                /* Register 3D resets ok to 0xc0: no LCD DAC */
-               /* Skip MNP setup, but samplerate-setup per phone may override */
+               /* TODO: Skip MNP setup, but samplerate-setup per phone may override */
+tlv320aic2x_setreg (chan, 4, 0x00 | ((6 & 0x0f) << 3) | (2 & 0x07));   // N:=6, P:=2
+tlv320aic2x_setreg (chan, 4, 0x80 | (16 & 0x7f));                      // M:=16
                tlv320aic2x_setreg (chan, 5, 0x00 | 0x12);      /* ADC gain 27 dB -- ok? */
                bottom_soundchannel_setvolume (chan, 15);       /* DAC gain -24 dB initially */
                tlv320aic2x_setreg (chan, 5, 0x80 | 0x00);      /* No sidetones */
index 1746e28..c080f7a 100644 (file)
@@ -116,8 +116,8 @@ void top_can_record (uint16_t samples) {
 }
 
 
-#define top_main_delay_1sec top_main
-// #define top_main_sine_1khz  top_main
+#define top_main_sine_1khz  top_main
+// #define top_main_delay_1sec top_main
 
 
 #ifdef CONFIG_FUNCTION_NETCONSOLE
@@ -129,14 +129,21 @@ void nethandler_llconly (uint8_t *pkt, uint16_t pktlen);
 
 /******** TOP_MAIN FOR A 1 KHZ SINE WAVE OUTPUT ********/
 
-uint8_t sinewave [8] = {
+uint8_t sinewaveL8 [8] = {
        0x00, 0x5a, 0x7f, 0x5a, 0x00, 0xa5, 0x80, 0xa5
 };
 
+uint16_t sinewaveL16 [8] = {
+       // 0x0000, 0x5a82, 0x7fff, 0x5a82, 0x0000, 0xa57e, 0x8001, 0xa57e
+       4096+0x0000, 4096+0x05a8, 4096+0x07ff, 4096+0x05a8, 4096+0x0000, 4096+0xfa57, 4096+0xf801, 409+0xfa57
+};
+
 void top_main_sine_1khz (void) {
        uint16_t oldirqs = 0;
 extern volatile uint16_t available_play;
+uint8_t l16ctr = 1;
        top_hook_update (bottom_phone_is_offhook ());
+       bottom_critical_region_end ();
        bottom_codec_play_samplerate (0, 8000);
        bottom_codec_record_samplerate (0, 8000); // Both MUST be called for now
        bottom_soundchannel_setvolume (PHONE_CHANNEL_TELEPHONY, 127);
@@ -150,11 +157,14 @@ extern volatile uint16_t available_play;
                        bottom_printf ("New playing IRQs detected\n");
                        oldirqs = plyirqs;
                }
+#if 1
+if (SPCR2_1 & REGVAL_SPCR2_XRDY) { DXR1_1 = sinewaveL16 [l16ctr++]; if (l16ctr == 8) { l16ctr = 0; } }
+#else
                while (newplayed >= 8) {
-                       bottom_codec_play (0, CODEC_L8, sinewave, 8, 8);
+                       bottom_codec_play (0, CODEC_L8, sinewaveL8, 8, 8);
                        newplayed -= 8;
-                       bottom_critical_region_end ();
                }
+#endif
 #if 0
                if (oldplayed != newplayed) {
                        bottom_printf ("available_play := %d\n", (intptr_t) available_play);
@@ -163,14 +173,17 @@ extern volatile uint16_t available_play;
 #endif
 
 #ifdef CONFIG_FUNCTION_NETCONSOLE
+               // { uint32_t ctr = 10000; while (ctr--) ; }
                trysend ();
+               // { uint32_t ctr = 10000; while (ctr--) ; }
 bottom_led_set (LED_IDX_BACKLIGHT, 1);
                netinputlen = sizeof (netinput);
                if (bottom_network_recv (netinput, &netinputlen)) {
                        nethandler_llconly (netinput, netinputlen);
-                       { uint32_t ctr = 10000; while (ctr--) ; }
 bottom_led_set (LED_IDX_BACKLIGHT, 0);
+                       { uint32_t ctr = 10000; while (ctr--) ; }
                }
+bottom_led_set (LED_IDX_BACKLIGHT, 0);
                trysend ();
 #endif
 
@@ -212,22 +225,6 @@ uint16_t loop = 0;
        bottom_printf ("Running the development function \"echo\" (Test sound)\n");
        while (true) {
 #if 0
-if (loop++ == 0) {
-uint8_t reg, subreg;
-uint8_t chan = PHONE_CHANNEL_TELEPHONY;
-for (reg = 1; reg <= 6; reg++) {
-uint8_t val0, val1, val2, val3;
-for (subreg = 0; subreg <=3 ; subreg++) {
-val0 = tlv320aic2x_getreg (chan, reg);
-val1 = tlv320aic2x_getreg (chan, reg);
-val2 = tlv320aic2x_getreg (chan, reg);
-val3 = tlv320aic2x_getreg (chan, reg);
-}
-bottom_printf ("TLV_%d = %02x, %02x, %02x, %02x\n", (intptr_t) reg, (intptr_t) val0, (intptr_t) val1, (intptr_t) val2, (intptr_t) val3);
-}
-}
-#endif
-#if 0
                if (recirqs != prevrecirqs) {
                        bottom_printf ("Record IRQs #%d, ", (intptr_t) recirqs);
                        bottom_printf ("available %d\n", (intptr_t) toberecorded);
@@ -239,7 +236,7 @@ bottom_printf ("TLV_%d = %02x, %02x, %02x, %02x\n", (intptr_t) reg, (intptr_t) v
                        prevplyirqs = plyirqs;
                }
 #endif
-{uint16_t xor = oldspcr1 ^ SPCR1_1; if (xor) { oldspcr1 ^= xor; bottom_printf ("SPCR1_1 := 0x%04x\n", oldspcr1); } }
+{ uint16_t xor = oldspcr1 ^ SPCR1_1; if (xor) { oldspcr1 ^= xor; bottom_printf ("SPCR1_1 := 0x%04x\n", (intptr_t) oldspcr1); } }
                if (sampled != prevsampled) {
                        bottom_printf ("Buffered %d samples\n", (intptr_t) sampled);
                        prevsampled = sampled;
@@ -286,6 +283,7 @@ bottom_led_set (LED_IDX_SPEAKERPHONE, 1);
 bottom_led_set (LED_IDX_HANDSET, 0);
                        }
                }
+
 #ifdef CONFIG_FUNCTION_NETCONSOLE
                // { uint32_t ctr = 10000; while (ctr--) ; }
                trysend ();
@@ -294,14 +292,17 @@ bottom_led_set (LED_IDX_BACKLIGHT, 1);
                netinputlen = sizeof (netinput);
                if (bottom_network_recv (netinput, &netinputlen)) {
                        nethandler_llconly (netinput, netinputlen);
-                       { uint32_t ctr = 10000; while (ctr--) ; }
 bottom_led_set (LED_IDX_BACKLIGHT, 0);
+                       { uint32_t ctr = 10000; while (ctr--) ; }
                }
+bottom_led_set (LED_IDX_BACKLIGHT, 0);
                trysend ();
 #endif
+
 #if defined NEED_KBD_SCANNER_BETWEEN_KEYS || defined NEED_KBD_SCANNER_DURING_KEYPRESS
                bottom_keyboard_scan ();
 #endif
+
 #if defined NEED_HOOK_SCANNER_WHEN_ONHOOK || defined NEED_HOOK_SCANNER_WHEN_OFFHOOK
                bottom_hook_scan ();
 #endif