at91sam7s64 help

Microchip in-system programming solution: SAM-BA

Moderators: nferre, fab

AndEvo
Posts: 5
Joined: Fri Mar 27, 2009 9:37 pm

at91sam7s64 help

Thu May 07, 2009 7:42 pm

Hi all, I'm new to programming this and am using the examples as a starting point. I'm trying to write a program that uses the RTT to take measurements from the adc and transmit them back to the pc via the usb. Eventually I would like to send the program a new update time to adjust the frequency of the transmitted signal. At present I have the RTT working with the USB sending strings back every second, but when I add the adc the program compiles fine but seems to crash straight away. I've posted the code below if someone can offer suggestions I'd be very greatful.

Thanks Andy

Code: Select all

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------

#include <board.h>
#include <pio/pio.h>
#include <dbgu/dbgu.h>
#include <aic/aic.h>
#include <adc/adc.h>
#include <pmc/pmc.h>
#include <rtt/rtt.h>
#include <utility/trace.h>
#include <usb/device/cdc-serial/CDCDSerialDriver.h>
#include <usb/device/cdc-serial/CDCDSerialDriverDescriptors.h>

#include <string.h>
#include <stdio.h>


void ConfigureRtt(int timeS);
static void ISR_Adc(void);

//------------------------------------------------------------------------------
//         Local definitions
//------------------------------------------------------------------------------

/// Device is in the main menu.
#define STATE_MAINMENU      0
/// User is setting an alarm time
#define STATE_SETALARM      1


/// Use for power management
#define STATE_IDLE    0
/// The USB device is in suspend state
#define STATE_SUSPEND 4
/// The USB device is in resume state
#define STATE_RESUME  5

/// Size in bytes of the buffer used for reading data from the USB & USART
#define DATABUFFERSIZE \
    BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)


/// State of USB, for suspend and resume
unsigned char USBState = STATE_IDLE;

/// Buffer for storing incoming USB data.
static unsigned char usbBuffer[DATABUFFERSIZE];

static int SendReady  = 0;


/// Indicates that the conversion is finished.
static volatile unsigned char conversionDone;

static float Freq = 1;
/// Define AT91C_BASE_RTTC if not already done
#if !defined(AT91C_BASE_RTTC)
    #define AT91C_BASE_RTTC     AT91C_BASE_RTTC0
#endif

/// Pio pins to configure.
#ifdef PINS_ADC
static const Pin pinsADC[] = {PINS_ADC};
#endif

/// ADC 
#define BOARD_ADC_FREQ 5000000
#define ADC_FREQ      10
#define ADC_VREF       3300  // 3.3 * 1000

#define ADC_NUM_1  ADC_CHANNEL_5
#define ADC_NUM_2  ADC_CHANNEL_6
#define ADC_NUM_3  ADC_CHANNEL_7
//#define ADC_NUM_4  ADC_CHANNEL_5

//////////////////////////////////////////////////////////////////////////////////////////
/* bits */
#define   BIT0        0x00000001
#define   BIT1        0x00000002
#define   BIT2        0x00000004
#define   BIT3        0x00000008
#define   BIT4        0x00000010
#define   BIT5        0x00000020
#define   BIT6        0x00000040
#define   BIT7        0x00000080
#define   BIT8        0x00000100
#define   BIT9        0x00000200
#define   BIT10       0x00000400
#define   BIT11       0x00000800
#define   BIT12       0x00001000
#define   BIT13       0x00002000
#define   BIT14       0x00004000
#define   BIT15       0x00008000
#define   BIT16       0x00010000
#define   BIT17       0x00020000
#define   BIT18       0x00040000
#define   BIT19       0x00080000
#define   BIT20       0x00100000
#define   BIT21       0x00200000
#define   BIT22       0x00400000
#define   BIT23       0x00800000
#define   BIT24       0x01000000
#define   BIT25       0x02000000
#define   BIT26       0x04000000
#define   BIT27       0x08000000
#define   BIT28       0x10000000
#define   BIT29       0x20000000
#define   BIT30       0x40000000
#define   BIT31       0x80000000

// SPI
AT91PS_SPI    s_pSpi = AT91C_BASE_SPI;
AT91PS_PIO    s_pPio = AT91C_BASE_PIOA;
AT91PS_PMC    s_pPMC = AT91C_BASE_PMC;
AT91PS_PDC    s_pPDC = AT91C_BASE_PDC_SPI;

// ADC
AT91PS_ADC    a_pADC = AT91C_BASE_ADC;
AT91PS_PMC    a_pPMC = AT91C_BASE_PMC;
AT91PS_PIO    a_pPio = AT91C_BASE_PIOA;
AT91PS_SYS   a_pSys = AT91C_BASE_SYS;

// GPIO and other
AT91PS_PIO    u_pPio    = AT91C_BASE_PIOA;
AT91PS_PMC    u_pPMC    = AT91C_BASE_PMC;
AT91PS_USART  u_pUSART0 = AT91C_BASE_US0;
AT91PS_USART  u_pUSART1 = AT91C_BASE_US1;
AT91PS_PDC    u_pPDC0   = AT91C_BASE_PDC_US0;
AT91PS_PDC    u_pPDC1   = AT91C_BASE_PDC_US1;
AT91PS_MC     u_pMC     = AT91C_BASE_MC;
AT91PS_AIC    u_pAic    = AT91C_BASE_AIC;

//------------------------------------------------------------------------------
//         Local variables
//------------------------------------------------------------------------------

 /// Current device state.
volatile unsigned char state;

/// New alarm time being currently entered.
volatile unsigned int newAlarm;

/// Indicates if an alarm has occured but has not been cleared.
volatile unsigned char alarmed;


#if defined (at91sam7s)
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
/// Put voltage regulator in standby mode
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
    // MCK=48MHz to MCK=32kHz
    // MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
    // MCK=SLCK : then change prescaler
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
    // disable PLL
    AT91C_BASE_PMC->PMC_PLLR = 0;
    // Disable Main Oscillator
    AT91C_BASE_PMC->PMC_MOR = 0;

    // Voltage regulator in standby mode : Enable VREG Low Power Mode
    AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;

    PMC_DisableProcessorClock();
}

//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
    // Voltage regulator in normal mode : Disable VREG Low Power Mode
    AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;

    // MCK=32kHz to MCK=48MHz
    // enable Main Oscillator
    AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );

    // enable PLL@96MHz
    AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
         (AT91C_CKGR_PLLCOUNT & (28<<8)) |
         (AT91C_CKGR_MUL & (0x48<<16)));
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
    AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
    // MCK=SLCK/2 : change prescaler first
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
    // MCK=PLLCK/2 : then change source
    AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK  ;
    while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );

}

#endif

//------------------------------------------------------------------------------
//         Local functions
//------------------------------------------------------------------------------



// Simple delay
void Delay (unsigned long a) {
  while (--a!=0);
}



//------------------------------------------------------------------------------
/// Callback invoked when data has been received on the USB.
//------------------------------------------------------------------------------
static void UsbDataReceived(unsigned int unused,
                            unsigned char status,
                            unsigned int received,
                            unsigned int remaining)
{
   int freq;
    // Check that data has been received successfully
    if (status == USBD_STATUS_SUCCESS) {
        // decode the string 
        // Decode the data recieved 
        if (received == sizeof(int)){
          //  flash the led so that we know data received
          // Configure RTT
          if ((freq >= 1) && freq <= 100) 
             ConfigureRtt(freq);
          
          
        }

        // Check if bytes have been discarded
        if ((received == DATABUFFERSIZE) && (remaining > 0)) {

            TRACE_WARNING(
                      "UsbDataReceived: %u bytes discarded\n\r",
                      remaining);
        }
    }
    else {

        TRACE_WARNING( "UsbDataReceived: Transfer error\n\r");
    }
}


void ADCInit (void)
{
   ADC_Initialize( AT91C_BASE_ADC,
                    AT91C_ID_ADC,
                    AT91C_ADC_TRGEN_DIS,
                    0,
                    AT91C_ADC_SLEEP_NORMAL_MODE,
                    AT91C_ADC_LOWRES_10_BIT,
                    BOARD_MCK,
                    BOARD_ADC_FREQ,
                    10,
                    1200);

    ADC_EnableChannel(AT91C_BASE_ADC, ADC_NUM_1);
    ADC_EnableChannel(AT91C_BASE_ADC, ADC_NUM_2);
    ADC_EnableChannel(AT91C_BASE_ADC, ADC_NUM_3);
  // ADC_EnableChannel(AT91C_BASE_ADC, ADC_NUM_4);

    AIC_ConfigureIT(AT91C_ID_ADC, 0, ISR_Adc);
    AIC_EnableIT(AT91C_ID_ADC);

}


void InitMMA(void) {

  //enable the clock of the PIO
  a_pPMC->PMC_PCER = 1 << AT91C_ID_PIOA;

  // Config
  // Configure all ports as Input
 // a_pPio->PIO_ODR           = 0xffffffff;       Delay(100);
  // Enable all ports
  //a_pPio->PIO_PER           = 0xffffffff;       Delay(100);
  // Disable Pull-up resistor
  //a_pSys->PIOA_PPUDR   = 0xffffffff;       Delay(100);


  // Set G_SEL1, G_SEL2 to low and SM to high
  a_pPio->PIO_SODR = 0x20000000;   // Set SM to HIGH
  a_pPio->PIO_SODR = 0x10000000;   // Set G_SEL1 to HIGH

//  a_pPio->PIO_CODR = 0x18000000;   // Set G_SEL1, G_SEL2 to LOW
  a_pPio->PIO_CODR = 0x08000000;   // Set G_SEL2 to LOW

  // Set G_SEL1, G_SEL2 and SM as output
  a_pPio->PIO_OER = 0x38000000;

}

//-----------------------------------------------------------------------------
/// Convert a digital value in milivolt
/// /param valueToconvert Value to convert in milivolt
//-----------------------------------------------------------------------------
static unsigned int ConvHex2mV( unsigned int valueToConvert )
{
    return( (ADC_VREF * valueToConvert)/0x3FF);
}

//------------------------------------------------------------------------------
/// Interrupt handler for the ADC. Signals that the conversion is finished by
/// setting a flag variable.
//------------------------------------------------------------------------------
static void ISR_Adc(void)
{
    unsigned int status;
    unsigned int id_channel;

    status = ADC_GetStatus(AT91C_BASE_ADC);
    //TRACE_DEBUG("status =0x%X\n\r", status);
    //TRACE_DEBUG("adc_imr=0x%X\n\r", ADC_GetInterruptMaskStatus());

    for(id_channel=ADC_NUM_1;id_channel<=ADC_NUM_3;id_channel++) {

        if (ADC_IsChannelInterruptStatusSet(status, id_channel)) {

            //TRACE_DEBUG("channel %d\n\r", id_channel);
            ADC_DisableIt(AT91C_BASE_ADC, id_channel);
            conversionDone |= 1<<id_channel;
        }
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for the RTT. Displays the current time on the DBGU.
//------------------------------------------------------------------------------
void ISR_Rtt(void)
{
    unsigned int status;
    char text[200];
    int i;
    float timeInc = 0.1 / Freq;
    static int numConv = 1;
   unsigned int id_channel;
   static double volt[8] = {0};
    // Get RTT status
    status = RTT_GetStatus(AT91C_BASE_RTTC);

    // Time has changed, refresh display
    if ((status & AT91C_RTTC_RTTINC) == AT91C_RTTC_RTTINC) {

       // RefreshDisplay();
    }

    // Alarm
    if ((status & AT91C_RTTC_ALMS) == AT91C_RTTC_ALMS) {

        alarmed = 1;
        //RefreshDisplay();
    }
    if (SendReady){
         conversionDone = 0;
   
        // Start measurement
        ADC_EnableIt(AT91C_BASE_ADC, ADC_NUM_1);
        ADC_EnableIt(AT91C_BASE_ADC, ADC_NUM_2);
        ADC_EnableIt(AT91C_BASE_ADC, ADC_NUM_3);
       // ADC_EnableIt(AT91C_BASE_ADC, ADC_NUM_4);

        // Start measurement
        ADC_StartConversion(AT91C_BASE_ADC);
  
        while( conversionDone != ((1<<ADC_NUM_1)|(1<<ADC_NUM_2)|(1<<ADC_NUM_3)) );
 
        for(id_channel=ADC_NUM_1;id_channel<=ADC_NUM_3;id_channel++) {
            Volt[id_channel] += ConvHex2mV(ADC_GetConvertedData(AT91C_BASE_ADC, id_channel));
        }        
        if (numConv == ADC_FREQ){
          //   update the information before sending
          // average out the voltage
          // Send current buffer through the USB
          // here i'm averaging the voltage over ten measurements then printing to string
          sprintf(text, "-- Count %d num %d --\n\r", count,numConv);
          while (CDCDSerialDriver_Write(text, (unsigned int)strlen(text), 0, 0) != USBD_STATUS_SUCCESS);  
       
          numConv = 0;
          // clear the voltages for next time
          for (i = 0; i < 8; i++){
            Volt[i] = 0;
          }
        }
        numConv++;      
       
    }
}

//------------------------------------------------------------------------------
/// Configures the RTT to generate a one second tick, which triggers the RTTINC
/// interrupt.
//------------------------------------------------------------------------------
void ConfigureRtt(int timeS)
{
    unsigned int previousTime;
    unsigned int timeStep = 32768;

    // if timeStep is zero the update 1s intervals
    if (timeS == 0){ timeStep = 32768;
    // else update the frequency
    } else {
      timeStep = 32768/timeS; 
    }

    // Configure RTT for a 1 second tick interrupt, 
    RTT_SetPrescaler(AT91C_BASE_RTTC, timeStep);
    previousTime = RTT_GetTime(AT91C_BASE_RTTC);
    while (previousTime == RTT_GetTime(AT91C_BASE_RTTC));

    // Enable RTT interrupt
    AIC_ConfigureIT(AT91C_ID_SYS, 0, ISR_Rtt);
    AIC_EnableIT(AT91C_ID_SYS);
    RTT_EnableIT(AT91C_BASE_RTTC, AT91C_RTTC_RTTINCIEN);
}



//------------------------------------------------------------------------------
//         Global functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Initializes the RTT, displays the current time and allows the user to
/// perform several actions: clear the timer, set an alarm, etc.
//------------------------------------------------------------------------------
int main(void)
{
    int i;

    // Enable DBGU
    TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
  
#ifdef PINS_ADC
    PIO_Configure(pinsADC, PIO_LISTSIZE(pinsADC));
#endif
    
    // Configure RTT
    ConfigureRtt(1);

    // BOT driver initialization
    CDCDSerialDriver_Initialize();

    // InitMAM
    InitMMA();

    // InitADC
    ADCInit();


    // Initialize state machine
    state = STATE_MAINMENU;
    alarmed = 0;
    
    // User input loop
    while (1) { 
        // Device is not configured
        if (USBD_GetState() < USBD_STATE_CONFIGURED) {

            // Connect pull-up, wait for configuration
            USBD_Connect();
            while (USBD_GetState() < USBD_STATE_CONFIGURED);
            // Start receiving data on the USB
            CDCDSerialDriver_Read(usbBuffer, DATABUFFERSIZE, (TransferCallback) UsbDataReceived, 0);

        }
        SendReady = 1;
    
       if( USBState == STATE_SUSPEND ) {
            //TRACE_DEBUG("suspend  !\n\r");
            LowPowerMode();
            USBState = STATE_IDLE;
        }
        if( USBState == STATE_RESUME ) {
            // Return in normal MODE
           // TRACE_DEBUG("resume !\n\r");
            NormalPowerMode();
            USBState = STATE_IDLE;
        }
    }
}

AndEvo
Posts: 5
Joined: Fri Mar 27, 2009 9:37 pm

Re: at91sam7s64 help

Sun May 10, 2009 10:14 pm

bump anyone???
AndEvo
Posts: 5
Joined: Fri Mar 27, 2009 9:37 pm

Re: at91sam7s64 help

Thu May 28, 2009 1:17 pm

anyone???

can anyone suggest where I should be looking in the code? common problems? etc

Thanks
Andy


Last bumped by AndEvo on Thu May 28, 2009 1:17 pm.

Return to “SAM-BA”

Who is online

Users browsing this forum: No registered users and 1 guest