HomeProduct Articles How to Program a Low Cost Sinusoidal Generator on the TMS320 Platform
How to Program a Low Cost Sinusoidal Generator on the TMS320 Platform
Alex Boudreau of SoftDB and Bruno Paillard of D-Box Technologies have submitted a new white paper titled "How to Program a Low Cost Sinusoidal Generator on the TMS320 Platform" on www.taylorriver.com. The article discusses the typical method used for programming sinusoidal generators, as well as the disadvatges to these approaches, and then illustrates a new, more effective method for programming sinusoidal generators on the TM2320 platforms.
"A typical task of a DSP system is to generate a sine signal. The traditional sinusoidal generation technique poses various problems when it is implemented on a low-cost, 16-bit fixed point DSP. During the design phase of a DSP application, if precision is required, engineers have a tendency to select a floating point DSP, resulting in a more expensive design.
The following text presents an alternative technique to generate a sinusoidal signal with a high precision, up to the highest frequencies on a low cost fixed point DSP. The implementation of this technique is very simple and uses less DSP resources (memory and CPU time) than the traditional approaches."
How to Program a Low Cost Sinusoidal Generator on the TMS320 Platform
Alex Boudreau, Director of the DSP division at Soft dB () Bruno Paillard, Director of Research and Development at D-Box Technologies.
CURRENT PROBLEMS WITH GENERATING A SINE SIGNAL
A typical task of a DSP system is to generate a sine signal. The traditional sinusoidal generation technique poses various problems when it is implemented on a low-cost, 16-bit fixed point DSP. During the design phase of a DSP application, if precision is required, engineers have a tendency to select a floating point DSP, resulting in a more expensive design.
The following text presents an alternative technique to generate a sinusoidal signal with a high precision, up to the highest frequencies on a low cost fixed point DSP. The implementation of this technique is very simple and uses less DSP resources (memory and CPU time) than the traditional approaches.
The two traditional techniques used to generate a sinusoidal signal are the lookup table and the sinusoidal approximation by a polynomial approximation. These two widely used techniques have some important disadvantages. The lookup table technique allows a high precision but, at low frequencies, the size of the table becomes very large. Also, this technique does not allow a precise and continuous adjustment of the frequency. The polynomial approximation technique lacks precision at high frequencies even with a high order series. As the sinusoidal angle grows to very large values, the process of folding it back between -p and + p for the polynomial computation brings increasing imprecision, which translates into noise.
TOOLS USED
The alternative technique discussed here has been developed, debugged and implemented using Soft dB’s Signal Ranger board with a TMS3205402 processor (the Signal Ranger Mk2 version with a TMS3205502 can also be used), the Fudantech TMS320 universal JTAG emulator and Texas Instrument’s Code Composer Studio, version 3.1.
ALTERNATIVE TECHNIQUE
With the proposed alternative technique, the sinusoidal generation is done by iterative rotation of a complex number. The next figure shows a representation of this number C in the complex plane for two successive iterations. The rotation of the vector C generates a circle with a radius of 1. The real part of the number C is used to generate the sinusoidal signal.
The rotation of the vector C is done by the multiplication by a vector Delta that represents the rotation step.
(1)
(2)
(3)
The initial value of C determines the initial phase of the generated sinusoid. The complex number Delta determines the rotation step and the frequency of the sinusoidal signal. The rotation calculation is very simple to implement on DSP since only a multiplication and an addition are used. But, for a fixed-point implementation, a small error on the amplitude of the complex number C is generated after each rotation step. This small error is accumulated and becomes large after many complete rotations. The next figure illustrates this problem.
To correct this problem, a normalization of the complex number C has to be done after each rotation step. The normalization is done using the following expressions:
(4)
(5)
The normalization requires the calculation of the square root of a number and two divisions. These non-ALU-supported operations are very expensive in terms of the CPU time on a fixed point DSP. To avoid them and minimize the computation time, an approximation of the expressions (4) and (5) is used. The expressions (4) can be reformulated in the following way:
(6)
e represents the error of the norm:
(7)
In the limit, for a zero error e, the equation (6) and (4) are equivalent. Between each rotation step, the error is very low and very close to zero. In this case, to make an approximation, we can use a first order Taylor series developed around zero (MacLaurin series):
(8)
(9)
With the approximation of the norm by equation (9), the implementation is greatly simplified since only an ALU-supported operation is performed (see the example code further in the text). Comparative tests of a sinusoidal generation with and without the norm approximation show that the approximation (9) does not degrade the quality of the generated sinusoidal. The following figure shows the time signal and the power spectrum of a sinusoidal generated with a normalization of the number C between each rotation step.
The sinusoidal amplitude does not decrease and the power spectrum shows the first harmonic at 80 dB below the fundamental. In this case, at very low frequency (0.1% of Fs), the presence of the first harmonic is due to the representation error of a small rotation step Delta. For higher frequencies, the harmonic amplitude is extremely low. For instance, with a sinusoidal generated at 10% of Fs, the harmonic amplitude is 95 dB less than the fundamental. The next figure shows this case.
The following section presents an implementation example of the technique described in this text. The assembler code is for the TMS320C5000 family.
;******************************************************* ; ; Sine generator ; ; - Input (Static variables passed by register) : ; ; AR2 (Cre), AR3 (Cim) ; AR4 (Dre), AR5 (Dim) ; ; - Output (Static variable) : ; ; Cre ; ; Alex Boudreau and Bruno Paillard ; ; Number of CPU cycle used : 33 cycles ; ;*******************************************************
.title "sine" .mmregs
;******************************************************* ; Assembler subroutine sine ; The context protection follows the C convention ;*******************************************************
.text
.global sine
sine:
; Context Protection
pshm ST1
; Set DSP mode SXM=OVM=FRCT=CPL=1
orm #0100001101000000b,*(ST1)
; Reserve two words on stack
frame -2
; *********** Sine calculation
; Real part calculation : Cre*Dre – Cim*Dim
mpy *ar2,*ar4,a ; a = Cre * Dre masr *ar3,*ar5,a,a ; a = rnd(a - Cim * Dim) sth a,*sp(0) ; sp(0) = ah (real part)
; Imaginary part calculation : Cim*Dre + Cre*Dim
mpy *ar4,*ar3,b ; b = Dre * Cim macr *ar2,*ar5,b,b ; b = rnd(b + Cre * Dim) sth b,*sp(1) ; sp (1) = bh (img. part)
; (2147352578(1^2) - sp(0)^2 - sp(1)^2) / 2
ld #0x7FFF,16,a ; a = 7FFFh<<16 squr a,a ; a = a * a = 32767^2 = 2147352578 squrs *sp(0),a ; a = a - sp(0)^2 squrs *sp(1),a ; a = a - sp(1)^2 add #1,15,a,a ; rnd a sfta a,-1,a ; a = a/2
; Update Cre and Cim
ld *sp(1),T ; Treg = sp(1) macar T,b,b ; b = rnd(b+ah*treg) ; b = rnd(sp(1)+(1-sp(0)^2-sp(1)^2)*sp(1)) sth b,*ar3 ; Cim = bh
ld *sp(0),T ; Treg = sp(0) ld *sp(0),16,b ; b = sp(0)<<16 macar T,b,b ; b = rnd(b+ah*treg) ; b = rnd(sp(0)+(1-sp(0)^2-sp(1)^2)*sp(0)) sth b,*ar2 ; Cre = bh