Subversion Repositories svnkaklik

Rev

Blame | Last modification | View Log | Download

/* 
 * Copyright (C) 2004 Darren Hutchinson (dbh@gbdt.com.au)
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Library General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA. 
 *
 * $Id: sr.c,v 1.4 2004/04/04 10:32:50 dbh Exp $
 */

/* This file contains the code to save and restore the "configurable
 * parameters" of the program. These are held in the internal EEPROM
 *
 * These functions are expected to be executed with interrupts enabled and
 * will not return until complete.
 */

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>

#include "stepper.h"
#include "paddle.h"

/* Define the staging structure used to save configurable parameters */
struct sr_s
{
    uint8_t     raFinPos;
    uint8_t     raFinNeg;
    uint16_t    raBacklash;

    uint8_t     decFinPos;
    uint8_t     decFinNeg;
    uint16_t    decBacklash;

    uint8_t     paddleGuideRate;

    int8_t      trackingRate;
    uint8_t     transRatio;

    uint8_t     csum;   // Two's complement of other fields
};

volatile uint8_t        doSave;

/* srSaveState() collects the configurable parameters from all over the
 * system and saves them into the EEPROM
 *
 * Passed
 *      Nothing
 *
 * Returns
 *      Nothing
 *
 * Notes:
 *      This function assumes that the interrupts are enabled on
 *      entry.
 */
void
srSaveState(void)
{
    struct sr_s         state;
    uint8_t             i;
    uint8_t             *p;

    /* Turn off the interrupts while we "snapshot" the current
     * state
     */
    cli();

    /* Copy the current state */
    state.raFinPos = raState.finPos;
    state.raFinNeg = raState.finNeg;
    state.raBacklash = raState.backlash;

    state.decFinPos = decState.finPos;
    state.decFinNeg = decState.finNeg;
    state.decBacklash = decState.backlash;

    state.paddleGuideRate = paddleGuideRate;
    state.trackingRate = trackingRate;
    state.transRatio = transRatio;

    /* Reenable interrupts */
    sei();

    /* Calculate the checksum of the structure */
    for (p = (uint8_t *)&state, i = 0 ; p != (uint8_t *)&state.csum ; )
         i += *p++;
    state.csum = i;

    /* Write the complete structure into the EEPROM */
    for (i = 0, p = (uint8_t *)&state ; i < sizeof(state) ; ++i, ++p)
    {
        /* Wait for EEWE to become zero (ie. EEPROM not writting) */
        while (EECR & _BV(EEWE))
            ;
        
        /* Setup the address */
        EEARH = 0;
        EEARL = i;
        
        /* Put the data in place */
        EEDR = *p;

        /* Perform the write */
        cli();
        EECR = _BV(EEMWE);
        EECR = _BV(EEMWE) | _BV(EEWE);
        sei();
    }

    /* All done */
}

/* srLoadState() reads the configurable parameters from EEPROM and copies
 * them to where they need to do.
 *
 * The data is protected by a checksum calculated when the data was
 * saved.
 *
 * Passed
 *      Nothing
 *
 * Returns
 *      Nothing
 *
 * Notes:
 *      This interrupt does not change the interrupt state and does
 *      not return until all the data is read
 */
void
srLoadState(void)
{
    struct sr_s         state;
    uint8_t             i;
    uint8_t             *p;

    /* Read the state data from the EEPROM */
    for (i = 0, p = (uint8_t *)&state ; i < sizeof(state) ; ++i, ++p)
    {
        /* Wait for EEWE to become zero (ie. EEPROM not writting) */
        while (EECR & _BV(EEWE))
            ;
        
        /* Setup the address */
        EEARH = 0;
        EEARL = i;

        /* Read the data. The device will stall until the data is
         * ready
         */
        EECR = _BV(EERE);

        /* Get the data */
        *p = EEDR;
    }

    /* Calculate the checksum of the structure. If it doesn't
     * match then the data is either corrupt or not initialized
     *
     * Either way keep the current data
     */
    for (p = (uint8_t *)&state, i = 0 ; p != (uint8_t *)&state.csum ; )
         i += *p++;
    if (state.csum != i)
        return;
    
    /* Copy the restored data to the current state */
    raState.finPos = state.raFinPos;
    raState.finNeg = state.raFinNeg;
    raState.backlash = state.raBacklash;

    decState.finPos = state.decFinPos;
    decState.finNeg = state.decFinNeg;
    decState.backlash = state.decBacklash;
    
    paddleGuideRate = state.paddleGuideRate;
    trackingRate = state.trackingRate;
    transRatio = state.transRatio;

    /* All done */
}