0,0 → 1,194 |
/* |
* 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 */ |
} |