Grandstream BT200 PCB

DSP processor, 2 MB Flash, 4 MB RAM, network, optional switch

BudgeTone general appearance; variations with 1 or 2 network ports.


Occurrence of this PCB

The BT200 PCB is used in the following device models:

This manufacturer also produces other models.

These devices are RoHS replacements for BT102 boards. The older BudgeTone models also have less memory to work with, which makes them a more suitable low-end model to consider for open telephony applications than the already more advanced BT200 models. Results will carry over easily, due to the similarity in hardware, and the larger models will then simply be able to take in more extra options.

Components found

Connectors found

These are described centrally in more detail:

The JTAG connector used in these GrandStream phones is a 14-pin connector. Its solder islands are open on the PCB, so soldering in a 0.1" pitched two-row pin header is easy.

On-board chip addressing

The DSP chip has 4 address areas, each linked to a CEn output. This makes it straightforward to select I/O hardware. The following scheme is used for BT200 phones:

pin external addresses wired functions mode internal addresses
/CE0 0x010000..0x3fffff Network 32 bit 0x012340..0x01234f (uint16_t at odd addresses)
/CE1 0x400000..0x7fffff Flash 16 bit 0x200000..0x2fffff
/CE2 0x800000..0xbfffff SDRAM 32 bit 0x400000..0x4fffff TODO:all/half?
/CE3 0xc00000..0xff7fff 8x D-FF to kbd/lcd 16 bit 0x666666

The external addresses are 8-bit addresses, whereas the actual addresses may be shifted up to accommodate their addressing mode. This is why a multiple of the actual address can fall into the external address range.

Since the configuration of these spaces is kind of complex, I decided to dump the start of the Flash from the address that the bootloader wants to get to. This yields a list of port settings that are made initially:

Register Value set Documentation
PLLCSR 0x0000  
EGCR1 0xff7f  
EGCR2 0x0009  
CE0_1 0x3f2f  
CE0_2 0xffff  
CE1_1 0x0922  
CE1_2 0x31f2  
CE2_1 0xff37  
CE2_2 unset  
CE3_1 0x0220  
CE3_2 0x0270  
SDC1 0x6ffe  
SDC2 0x8712  
SDRC1 0xf5dc  
SDRC2 0xffff  
SDX1 0xb809  
CESCR1 0xfffc  

Between most of these register updates, there is a 5-cycle wait; at the end, there is a 50-cycle wait.

SDRAM setup

The SDRAM W9816G6 has 2 banks, 11 row address bits (A10..A0), 8 column address bits (A7..A0) and a bus width of 16 bits. There are two such chips, totalling 32 bits.

The entire memory therefore comprises of 2 * 2^11 * 2^8 words of 32 bits, or a million 32 bit words, or 4 megabytes of memory.

(Is this correct?!? The banks are also an address bit? Or is A0 meaningless for 16 bit mode? The chips are 2 banks * 512 k * 16 bit each.)

See above for the actual values that make it all work nicely.

Network chip connections

The following table shows how the network chip KSZ8842-16 is connected to the DSP and to fixed signals:

KSZ8842-16 Routed to TMS320VC5501PGF or fixed signal
A15..A10 GND (0x0030 to 0x003f)
A9..A8 Vcc (0x0030 to 0x003f)
A7..A4 GND (0x0030 to 0x003f)
A3..A1 A4..A2 (connects shift-up in 16-bit async EMIF mode)
EEDI Vcc (mode 16-bit)

The network chip is not configured from EEPROM, so the MAC address must be assigned by the firmware. The network chip is configured as a 16-bit device, using the EMIF /BE0 and /BE1 signals to select the lower and/or higher parts of a word.

Note how the address is hardwired to its default range, 0x0300 to 0x030f by fixed values for A15..A4. The only address bits that actually select an address are the A3..A1 bits. Due to this, the ethernet chip is omnipresent in its /CE0 space.

When scanning for this chip's presence... I sent 0xffff to each word in the /CE0 space, and looked where it popped up. I never realised that my first actual, writing to register 0x0 or BAR, was to change the address to 0xffff making it unreachable, in light of the fixed wiring of most of the address lines. Doh!

Clock regime

Following is how we define the clock signals of the BT200 phone.

To support various sample rates, the proper division value should be set in FPER:

Sample rate RFC3551 Divide by FPER setting Codecs
8000 Hz Yes 1536 1535 G.7xx, GSM, iLBC, L16, ...
11025 Hz Yes 1114,5578... 1113 or 1114 L16, ...
16000 Hz Yes 768 767 G.722, G.722.1, L16
22050 Hz Yes 557,27891... 556 or 557 L16
32000 Hz Yes 384 383 L16, ?
44100 Hz Yes 278,63946... 277 or 278 AAC, MP3, Vorbis, CD, L16
48000 Hz Yes 256 255 AAC, MP3, Vorbis, DAT, L16
96000 Hz No 128 127 AAC

Note that 44100 Hz, the CD sample rate and also a popular MP3 and Vorbis sample rate, is a bit of a nuisance; it is the multiplication of squares of the first four prime numbers (2*2*3*3*5*5*7*7 = 44100) which looks like a nerdy form of fun, but it actually makes generating this rate extremely difficult. The frequencies involved in the DSP's clock rate includes many powers of 2 and 5, and the PLL could even introduce 3*3 or 7, but there is no way to factor in 3*3*7*7 with the PLL. In other words, we cannot derive an accurate 44100 Hz sample rate from this architecture.

The McBSP structures in the DSP have an ability to repeat the last sample if it is not handed one in time, which probably is a reasonable solution for problems like these. By rounding down the value in FPER, this would automatically be triggered. For CD sample rates, the inserted extra sample would only be done for 0,36% of the samples. For lower sample rates, the error percentage is even less.

The L16 codec entries refer to RFC 3551, which prescribes a number of audio formats to transmit over RTP. Other formats that also support variable bitrates are equally possible, but less likely: L8, PCMA, PCMU. One additional function that a phone could perform is playing such samples; L16 is the most likely candidate to be doing that. RTP might be multicasted on a LAN, from another phone or from a desktop running a suitable bit of software (like PulseAudio doing RTP Multicast in s16ne or s16be mode, or gstreamer using its rtpL16pay module).

There is one more constraint however. It is rather clumsy: the codec itself divides the MCLK signal of 12,288 MHz internally, by a product of factors 128.M.N.P where P is 1 or 8, M=1..128 and N=1..16. This is used to achieve an oversampled clock rate for its filters. Interestingly, the design does include a PLL, but it has not been used for this purpose. Don't ask me why... anyhow, the resulting constraints means that factors M, N and P must be determined. In practice, P=1 is the only useful setting for that factor, but the others can be manipulated:

Sample rate 128.M.N.P M N P OSR
8000 Hz 1536 12 1 1 512
11025 Hz 1114,5578... 9... 1 1 128
16000 Hz 768 6 1 1 256
22050 Hz 557,27891... 5... 1 1 128
32000 Hz 384 3/pass 1/thru 1 128
44100 Hz 278,63946... pass thru 1 128
48000 Hz 256 pass thru 1 128
96000 Hz 128 pass thru 1 128

Note that N adds nothing, because the factors are small enough to always fit inside M. The dotted values are inaccurate, and hoped not to confuse playback too much. The pass/thru values are another matter; the filters can be switched off for those, so no oversampling rate has to be generated. (TODO: But does it actually work that way in this confused codec design?)

The oversampling rate OSR can be set to 128, 256 or 512; the table indicates the highest setting, thus the one yielding the best audio quality, possible for the given values. This does not exceed the advised maximum values from the datasheet, and it has one (for 256) or two (for 512) low-value bits in M set to zero.

One point of attention however, is that the 32 kHz sample rate should use a filter to remove frequency components above the 16 kHz Nyquist frequency, but that the codec cannot perform up to that level. For that reason, the filters have to be bypassed and it is to be hoped that the speakers used won't be able to render such high frequencies at any audible level. This renders the TLV320AIC2x codecs unsuitable for general purpose HiFi rendering -- which is acceptable for a normal phone, but is likely to render the chip useless for future designs based on the 0cpm Firmerare. (Note however, that an AC'97 codec can also be driver from an McBSP link.)

DMA regime

To get a very consistent rate for audio, we have it arranged by DMA. Channel 0 plays samples from a sample buffer out to the sound codec, channel 1 records what comes back from it.

The FS clock described above gives the timing for the McBSP1 serial port connected to the codec chip, and DMA channels 0 and 1 are synchronised to the McBSP1 transmit and read events, respectively.

The DMA is continuously running over the sample buffer, at least in theory. In practice, it detects once every 64 samples if there are enough samples to continue, and if not, that channel stops. As soon as new samples are injected, DMA is (re)started. After boot, the sample buffer is empty, so the DMA channels is prepared but not yet started.

While copying data from (usually) RTP to the sample buffer, any translation scheme can be employed, like from G.726 / ADPCM to 16-bit samples. This translation is done by the bottom, and may therefore involve assembler code or even hardware support. So, on platforms that have MP3, Vorbis or AAC decoding abilities, or perhaps in some future even support for MPEG2, MP4 and Theora, this is where these facilities are put to use. It could prove to be a good idea to build Vorbis/Theora encoding into a high-end phone for meeting rooms, especially because stereo effects can be really helpful to position "the others" on the other side of a table.

Sound codec connections

The following table shows how the codec (sound) chip is connected to the DSP. It is probably the TLV320AIC20K which is also used in other models by Grandstream; all assumptions based on that seem to work out fine.

TLV320AIC2x Routed to TMS320VC5501PGF or fixed signal
MCLK ECLKOUT2 (24.576 MHz under original firmware)
SCLK CLKR1, CLKX1 (12.288 MHz under original firmware)
M/S Low, so: stand-alone slave mode
/PRWDWN High, so: use software power down
/RESET GPIO7 -- took me ages to discover why the Codec was not listening!
MICBIAS Provides 2.35 Volt

Clearly, the I2C facility can be used to instruct the codec without interfering with the data stream. That means that it is not necessary to resolve to other funny ways that the codec chip offers for control. In other words, the McBSP1 interface to which it connects can be solely used for the exchange of samples.

The high frequency from ECLKOUT2 causes the codec to operate in turbo mode, where the sample data is swiftly exchanged after an FS dropping edge, followed by high-impedance silence on the line. Indeed, scope images show a sharp burst of activity at regular intervals, followed by an exponential curve for the remainder of the sample period. That was a bit strange to experience on a digital line and is good to have explained ;-)


This is really confusing at first --the exponential forms should not appear on a digital line-- but it is the result of the high impedance state that both ends of these serial data lines end in when they have exchanged the bits for a sample period. As can be seen, the last bit exchanged can be a 1 or 0, influencing the result.


Zooming in on the previous measurement's time, the shapes make a lot more sense to our square eyes. Clearly, some bits are exchanged and then the line is left to its own devices, causing the exponential drop shown above. Clearly, turbo mode is used to exchange a single sample of 16 bits in just a small portion of the sample period.


I couldn't resist this "birth announcement" where, after incredibly long fights with the system, I finally manage to get the information clocked out as I want them to. This is the pattern 0xa5cf being shown clearly (binary that is 1010010111001111). Note how the start of this signal has fallen to halfway the supply voltage as a result of a digital line that floated before this bitstream was sent.


Here's a really dirty trick -- a way to test if a line is high-impedance at the proper times. This is the FS signal (the high peak) on the codec short-circuited with the next pin, with the DIN signal. As you can see, FS shows full power, so it is not pulled down by the low state of DIN; but the low state of FS does pull the voltage of DIN down to half its value. In other words, DIN is high impedance while FS occurs, which is how it should be. (Earlier models, like during the previous picture, had an FS that was wider and that would show trouble.) As this is a deliberate short-circuit, it is highly abusive; but it occurs when you are measuring a lot, and it's good to recognise a valuable pattern when you see one.

Even though this looks strange, it is actually proper engineering -- this is done to turn the serial connection into a sort of bus, where multiple codecs can be connected to one serial line and each gets their own time slot. The frame sync starts off the first codec which will, as soon as it is done, pass a delayed frame sync to the next codec, and so on. This can only be done when the codecs are using high impedance modes while another codec is (or may be) using the bus.

The codec won't generate its own SCLK signal, because it is setup as a slave. The generation of this signal has to be done by the DSP, which can use the McBSP-builtin sample rate generator to clock out CLKX1 or CLKR1, receive the other, and do the same with FSX1 and FSR1.

Sound codec registers

The BT200 only uses channel 0 of the codec. The registers in channel 1 are kept to the following settings:

1A=49 2A=a0 3A=01 3B=40 3C=88 3D=ff 4A=90 5A=00 5B=40 5C=bf 5D=c0 6A=00 6B=80

The settings of the other registers is mostly constant:

1A=49 2A=a0 3A=01 3B=40 3C=8a 3D=ff 4A=90 5A=** 5B=** 5C=bf 5D=c0 6A=** 6B=**

The values starred above differ, however:

Mode Register Meaning
On-hook 5A ADC gain, meaningless, 1f
On-hook 5B DAC gain, meaningless, 5e
On-hook 6A Input from handset, 02
On-hook 6B Output to handset, a2
Off-hook 5A ADC gain, variable, found 0c
Off-hook 5B DAC gain, variable
Off-hook 6A Input from handset, 02
Off-hook 6B Output to handset, 92
Speakerphone 5A ADC gain, variable, found 17, 19
Speakerphone 5B DAC gain, variable
Speakerphone 6A Input from microphone, 01
Speakerphone 6B Output to headset, 81

Values like these can be set. For instance:

bash$ bin/i2cp/aic2x-setup /dev/i2c-2 0x40 4A=0x32 4B=0x90

The command parameters have the following meaning:

This example may be a bit surprising; but the values of M, N and P are really stored in separate subregisters, even if the datasheet chooses to ignore that term in explaining register 4. The other (sub)registers are however implemented conforming the datasheet.