Discussion in "ARM Development" started by    abbas1707    Apr 29, 2008.
Tue Apr 29 2008, 03:38 pm
#1
hi bros,

i have a very lazy friend.he has been given a project ( to complete in class) which is based on ARM.Now the problem is that he has copied a project from internet,but he dont know what the code is doing actually..or what code can do.now its my headache to help him...but i dont know much about ARM.
Can anyone help me understanding that code?? so that i can help him. :-s

Code:
//=====================================================================
// Sean Finn, FYP 2006
// Embedded C control program for the ARM microcroller used
//        as core of the ETU
//
//---------------------------------------------------------------------
// Operation:
// Samples EKG & stethoscope signals (attached to ADC channels 0 & 1,
//        respectively), at 2.5 kHz & 500 Hz      (respectively).
// These 12 bit samples are then sent, a nibble at a time, to
//        Server PC thorough UART at 115200 baud (no parity, 2 stop bits)
//=====================================================================

#include <ADuC7024.h>
  //include definitions specific to eval board used

// function prototypes: definintions in seperate source file
extern int write (int file, char * ptr, int len);    // outputs a string on UART (for debug)     
extern int put_byte(int);                             // outputs a byte via UART 
extern void send_pak(unsigned char* buffer, int buff_size);          //sends the entrire Tx buffer
extern void initialise(void);                          // performs ARM initialisation (peripherals etc)
extern void IRQ_func(void);                            // ADC interrupt servive routine

//global variables

// variables associated with ADC conversions
unsigned short xn = 0;
unsigned short xn2 =0;
unsigned short samp_ctr = 0;
unsigned short pak_ctr = 0;
unsigned short dwnsmpl_ctr = 0;
static unsigned short dwnsmpl_ratio = 5; // 500 Hz EKG sampling frequency

// buffer variables
unsigned int buffer_size = 6012;
unsigned char send_buff1[6012] = {0};     // circular transmitt buffer
unsigned char buffer_full = 0;             // buffer full flag
unsigned char buff_send_margin = 99;     // send margin, to avoid buffer overrun (must be multiple of 3)
unsigned char* UART_ptr;                  // pointer to address the transmit buffer

//filtering variables, redundant here (see note below)
// filter co-efficients
//unsigned short co_efs[21] = {46637,49888,52926,55711,58208,60382,62202,63644,64689,
//                            65322,65535,65322,64689,63644,62202,60382,58208,55711,52926,
//                            49888,46637};  //20th order LPF   
//static unsigned char FILT_ORD = 20;           //order of the digital LPF implemented
//unsigned short mem[20] = {0};               //filters memory elements, of size FILT_ORD
//unsigned short filtered_smpl;

int main (void)  {
    //char output1[13] = "Hello World!\n";      // debugging UART test

    // pefore ADC is enabled, set up buffer, point pointer to first element of buffer array
    UART_ptr = &send_buff1[0];

    initialise();    //initialise peripherals: UART, ADC, etc

    // Set up the IRQ
    FIQ = IRQ_func;             //    Specify (Fast) Interrupt Service Rountine
    FIQEN = 0x8;                // enable timer 1 IRQ mask
    GP4DAT ^= 0x00040000;        // Complement P4.2 (LED), to indicate program is started

    // Main functionality handled by ADC ISR
    // Infinite loop, poll for full buffer flag, calling send_pak function when detected
    while(1)
    {                       
        if( buffer_full == 1) {     
            GP4DAT ^= 0x00040000;                // Complement P4.2 (LED)
            send_pak(UART_ptr, buffer_size);    // send the packet
            UART_ptr = &send_buff1[0];            // reset send pointer
            buffer_full = 0;                     // reset eand flag
        }
    }
}

//=============ADC interrupt servive routine=========================
// Medodology: Timer 1 triggers a conversions at 2.5 kHz, and a
//    sthethoscope  sample is read & stored in buffer.
//  Upon every 5th such conversion (ie at 500 Hz), a software
//    triggeredconversion of EKG channel is performed.
//
//    In prevoius versions, both were sampled at higher rate, and the
//    EKG was low pass filtered, and then downsampled. In this version
//  filtering code is commented (no downsampling =>
 no filtering required).
//====================================================================


void IRQ_func(void) {
    //unsigned short j;            // local counter declaration (filtering)
    GP1DAT ^= 0x00800000;        // Complement P1.7     (debug - ADC freq probing)
       T1CLRI = 0;                    // clear timer 1 interrupt flag
    xn = (ADCDAT >
>
 16) & 0xFFF;        // read ADC sample
   
    // nibble by nibble sample stroage. MS nibble of each byte is a counter,
    // used for decoding data stream at PC server                                                                                                                                                                         
    //store steth sample in byte-wide buffer: MSNibble, MiddleNibble LSNibble
    send_buff1[samp_ctr] = 0x40 | (xn >
>
 8);
    samp_ctr++;
    send_buff1[samp_ctr] = 0x20 |  ((xn >
>
 4) & 0xF);
    samp_ctr++;
    send_buff1[samp_ctr] = 0x10 | (xn & 0xF);
    samp_ctr++;

    if(dwnsmpl_ctr == dwnsmpl_ratio -1) { // every 5th sample
        GP1DAT ^= 0x00010000;        // Complement P1.0    (debug - ADC freq probing)        
        //perform a signle sofware driven ADC conversion from chan 1
        ADCCP = 0x01;                //switch ADC channel
        ADCCON = 0xE3;                // config for a software conversion       
        while (!ADCSTA){}            // wait for end of conversion
        xn = (ADCDAT >
>
 16);        // read ADC sample
        ADCCP = 0x07;                // select steth channel (1) again
        ADCCON=0xE1;                //return ADC config to timer 1 driven conversions

        // Digital filtering, now redundant.
        //--------EKG sample now read, perform filtering------------//
        //filtered_smpl = co_efs[0]*xn;
        //for(j=1;j<FILT_ORD;j++) {
        //    filtered_smpl += co_efs[j]*mem[j-1];
        //}
        //update memory elements
        //for(j=FILT_ORD;j>
0;j--){
        //    mem[j] = mem[j-1];
        //}
        //mem[0] = xn;
        //------Digital Filtering Complete-----------------------//

        //store the sample, samp method as for steth samples
        xn = (ADCDAT >
>
 16)& 0xFFF;
        send_buff1[samp_ctr] = 0xC0 | (xn >
>
 8);
        samp_ctr++;
        send_buff1[samp_ctr] = 0xB0 |  ((xn >
>
 4) & 0xF);
        samp_ctr++;
        send_buff1[samp_ctr] = 0xA0 | (xn & 0xF);
        samp_ctr++;

        dwnsmpl_ctr = 0;        //reset counter
    } else {
           dwnsmpl_ctr++;            //increment counter
    }

    // watch for buffer almost full
    if (samp_ctr == buffer_size - buff_send_margin) {
         buffer_full = 1;    // set the buffer full flag, main() will begin transmission
    } else if (samp_ctr == buffer_size) { //at the end of buffer, start filling from start again
        samp_ctr = 0;        //reset sample counter
        pak_ctr++;
       
    }
}
//=====================================================================
// Final Year Project ARM functions
// Sean Finn, 2006
//=====================================================================
#include <aduc7024.H>
      //include definitions specific to eval board used               

#define CR     0x0D      //define ASCII code for carrige return, for string Tx

// standard delay routine
void delay(int length)
{
    while (length >
=0)
        length--;
}

// outputs a byte via UART
int put_byte(unsigned int ch)  {                 

    if (ch == '\n')  {       // handle sending of newline
        while(!(0x020==(COMSTA0 & 0x020)))    //wait for UART not busy
        {}
        COMTX = CR;                           
        }
    while(!(0x020==(COMSTA0 & 0x020)))        //wait for UART not busy
    {}

    return (COMTX = ch);
}

//sends the entrire Tx buffer
void send_pak(unsigned char* buffer, int buff_size)
{
        unsigned int i;
        delay(1000);
        for(i=0;i<buff_size;i++) {    // loop through Tx buffer
            put_byte(*(buffer+i));    // send current byte using pointer arithmetic
        }
}

// outputs a string on UART (for debug)
int write (int file, char * ptr, int len) {
  int i;

  for (i = 0; i < len; i++) put_byte (*ptr++);
  return len;
}

// performs ARM initialisation (peripherals etc)
void initialise(void) {
   
    // UART configuration for 115200 baud
    GP1CON = 0x011;        // Setup tx & rx pins on P1.0 and P1.1
    COMCON0 = 0x80;        // Setting DLAB
       COMDIV0 = 0x0C;        // Setting DIV0 and DIV1 to DL calculated
       COMDIV1 = 0x00;
       COMCON0 = 0x07;        // Clearing DLAB
    COMDIV2 = 0x884F;

    //ADC configuration
    ADCCON=0x20;    //power-on the ADC
    delay(80000);    //wait for ADC poweron time
    ADCCP=0x00;        //Select ADC channel 0 by default
    ADCCON=0xE1;    //single-ended, start conversion on timer1
    REFCON=0x01;    //connect internal 2.5V reference to VREFpin

    // timer1 configuration                     
    T1LD = 0x467;                       // Counter Value (for 2.5 kHz)
    T1CON = 0xC4;                        // Enabled,Periodic,Binary
      
    // IO ports initialisation
    GP1DAT = 0xFF000000;       
    GP3DAT = 0xFFFF0000; 
    GP4DAT = 0x04000000;            // P4.2 configured as an output. LED is turned on 
}
Thu May 01 2008, 03:59 pm
#2
shyam bhai,
can you help me regarding this ?:(
Thu May 01 2008, 04:44 pm
#3
hi abbas hope i am not late

Samples EKG & stethoscope signals (attached to ADC channels 0 & 1,
respectively), at 2.5 kHz & 500 Hz (respectively).
These 12 bit samples are then sent, a nibble at a time, to
Server PC thorough UART at 115200 baud (no parity, 2 stop bits)



lets see how the code works..


lets first collect what devices we shall be requiring
1. 2 ADC channels
2. 1 UART port (Tx Rx)
3. Timer to set the interrupt (to read the adc)
4. GPIOs to connect LEDs (to show the response /result)

we have to initialise all these devices first..

void initialise(void)



the above function does it.. the comments are self axplainatory.. still we can discuss each of the statements.

the main part is to scan the two ADC pins for data..
ARM has several interrupt sources one of them is IRQ the other is FIQ
dont really know y ur frnd used FIQ here.. still FIQ is faster than IRQ.

so we need to write an IRQ ISR

void IRQ_func(void) {



the above function does it. The ISR collects the adc values and stores it in a buffer
send_buff1

now the stored data is needed to send thru UART and the leds needed to be controlled

so in main()
step1. call the initialisation
step2. point the FIQ to the fun PTR of your ISR
step3. enable the interrupt source i.e timer in FIQ mode
step4. start an never ending loop to transmit collected data and toggle the respective pins.


actually been busy these few days so cud not reply on time
 abbas1707 like this.
Fri May 02 2008, 05:00 am
#4
Thanks a ton bhai :-)

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

AntoniaRoons
Fri Apr 19 2024, 09:59 pm
carpinteyrowrl
Fri Apr 19 2024, 02:51 pm
DonaldJAX
Fri Apr 19 2024, 01:08 pm
Lewisuhakeply
Thu Apr 18 2024, 06:00 pm
Darrellciz
Thu Apr 18 2024, 11:07 am
Charlessber
Thu Apr 18 2024, 09:29 am
BartonSem
Thu Apr 18 2024, 04:56 am
DonaldKnown
Thu Apr 18 2024, 12:24 am