1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-20 14:54:31 +01:00

Removing avrlib (since it's not used), and switching to non-locking versions of RXTX for the Mac (separate PPC and Intel versions). Also, removed the __MACOSX file from tools-intel.zip.

This commit is contained in:
David A. Mellis 2006-12-19 15:21:24 +00:00
parent daf909cc1a
commit 18951f0437
149 changed files with 2 additions and 23931 deletions

View File

@ -168,7 +168,6 @@
/* End PBXApplicationTarget section */
/* Begin PBXBuildFile section */
330B21540968180400345666 /* librxtxSerial.jnilib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 330B21530968180400345666 /* librxtxSerial.jnilib */; };
332D4DB609CF147F00BF81F6 /* Sizer.java in Sources */ = {isa = PBXBuildFile; fileRef = 332D4DB509CF147F00BF81F6 /* Sizer.java */; };
336EA55B09FF87F60052D765 /* examples in CopyFiles */ = {isa = PBXBuildFile; fileRef = 336EA4DB09FF87E30052D765 /* examples */; };
338C478A0AA204BE008F2C0D /* FTDIUSBSerialDriver_v2_1_6.dmg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 338C47870AA204B0008F2C0D /* FTDIUSBSerialDriver_v2_1_6.dmg */; };
@ -411,16 +410,13 @@
339514FA097AEB8000193C89 /* license.txt in CopyFiles */,
339514FB097AEB8000193C89 /* readme.txt in CopyFiles */,
33FF07050965BEE60016AC38 /* macosx_setup.command in CopyFiles */,
330B21540968180400345666 /* librxtxSerial.jnilib in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
330B21530968180400345666 /* librxtxSerial.jnilib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.bundle"; path = librxtxSerial.jnilib; sourceTree = "<group>"; };
332D4DB509CF147F00BF81F6 /* Sizer.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; path = Sizer.java; sourceTree = "<group>"; };
333269E1099BB1FC007D3AE2 /* tools.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = tools.zip; sourceTree = "<group>"; };
336EA4DB09FF87E30052D765 /* examples */ = {isa = PBXFileReference; lastKnownFileType = folder; path = examples; sourceTree = "<group>"; };
337CD3F309EFC183002B890C /* fetch.sh */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = fetch.sh; sourceTree = "<group>"; };
338C47870AA204B0008F2C0D /* FTDIUSBSerialDriver_v2_1_6.dmg */ = {isa = PBXFileReference; lastKnownFileType = file; path = FTDIUSBSerialDriver_v2_1_6.dmg; sourceTree = "<group>"; };
@ -987,8 +983,6 @@
33FFFEAC0965BD110016AC38 /* dist */ = {
isa = PBXGroup;
children = (
333269E1099BB1FC007D3AE2 /* tools.zip */,
330B21530968180400345666 /* librxtxSerial.jnilib */,
33FFFEAE0965BD110016AC38 /* bootloader */,
33FFFEB20965BD110016AC38 /* drivers */,
33FFFEB50965BD110016AC38 /* DS_Store */,
@ -1078,7 +1072,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "unzip -od $BUILT_PRODUCTS_DIR dist/tools-ppc.zip";
shellScript = "unzip -od $BUILT_PRODUCTS_DIR dist/tools-ppc.zip\ncp dist/librxtxSerial-ppc.jnilib $BUILT_PRODUCTS_DIR/librxtxSerial.jnilib";
};
3318B11A0AD6CE9F00FE1A05 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -1091,7 +1085,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "unzip -od $BUILT_PRODUCTS_DIR dist/tools-intel.zip";
shellScript = "unzip -od $BUILT_PRODUCTS_DIR dist/tools-intel.zip\ncp dist/librxtxSerial-intel.jnilib $BUILT_PRODUCTS_DIR/librxtxSerial.jnilib";
};
3318B1520AD6D1EB00FE1A05 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;

BIN
build/macosx/dist/librxtxSerial-intel.jnilib vendored Executable file

Binary file not shown.

BIN
build/macosx/dist/librxtxSerial-ppc.jnilib vendored Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,116 +0,0 @@
/*! \file a2d.c \brief Analog-to-Digital converter function library. */
//*****************************************************************************
//
// File Name : 'a2d.c'
// Title : Analog-to-digital converter functions
// Author : Pascal Stang - Copyright (C) 2002
// Created : 2002-04-08
// Revised : 2002-09-30
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "a2d.h"
// global variables
//! software flag used to indicate when
//! the a2d conversion is complete
volatile unsigned char a2dCompleteFlag;
// functions
//! initialize a2d converter
void a2dInit(void)
{
sbi(ADCSR, ADEN); // enable ADC (turn on ADC power)
cbi(ADCSR, ADFR); // default to single sample convert mode
a2dSetPrescaler(ADC_PRESCALE); // set default prescaler
a2dSetReference(ADC_REFERENCE); // set default reference
cbi(ADMUX, ADLAR); // set to right-adjusted result
sbi(ADCSR, ADIE); // enable ADC interrupts
a2dCompleteFlag = FALSE; // clear conversion complete flag
sei(); // turn on interrupts (if not already on)
}
//! turn off a2d converter
void a2dOff(void)
{
cbi(ADCSR, ADIE); // disable ADC interrupts
cbi(ADCSR, ADEN); // disable ADC (turn off ADC power)
}
//! configure A2D converter clock division (prescaling)
void a2dSetPrescaler(unsigned char prescale)
{
outb(ADCSR, ((inb(ADCSR) & ~ADC_PRESCALE_MASK) | prescale));
}
//! configure A2D converter voltage reference
void a2dSetReference(unsigned char ref)
{
outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6)));
}
//! sets the a2d input channel
void a2dSetChannel(unsigned char ch)
{
outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
}
//! start a conversion on the current a2d input channel
void a2dStartConvert(void)
{
sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
sbi(ADCSR, ADSC); // start conversion
}
//! return TRUE if conversion is complete
u08 a2dIsComplete(void)
{
return bit_is_set(ADCSR, ADSC);
}
//! Perform a 10-bit conversion
// starts conversion, waits until conversion is done, and returns result
unsigned short a2dConvert10bit(unsigned char ch)
{
a2dCompleteFlag = FALSE; // clear conversion complete flag
outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
sbi(ADCSR, ADSC); // start conversion
//while(!a2dCompleteFlag); // wait until conversion complete
//while( bit_is_clear(ADCSR, ADIF) ); // wait until conversion complete
while( bit_is_set(ADCSR, ADSC) ); // wait until conversion complete
// CAUTION: MUST READ ADCL BEFORE ADCH!!!
return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits);
}
//! Perform a 8-bit conversion.
// starts conversion, waits until conversion is done, and returns result
unsigned char a2dConvert8bit(unsigned char ch)
{
// do 10-bit conversion and return highest 8 bits
return a2dConvert10bit(ch)>>2; // return ADC MSB byte
}
//! interrupt handler for ADC complete interrupt
SIGNAL(SIG_ADC)
{
// set the a2d conversion flag to indicate "complete"
a2dCompleteFlag = TRUE;
}

View File

@ -1,141 +0,0 @@
/*! \file a2d.h \brief Analog-to-Digital converter function library. */
//*****************************************************************************
//
// File Name : 'a2d.h'
// Title : Analog-to-digital converter functions
// Author : Pascal Stang - Copyright (C) 2002
// Created : 4/08/2002
// Revised : 4/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef A2D_H
#define A2D_H
// defines
// A2D clock prescaler select
// *selects how much the CPU clock frequency is divided
// to create the A2D clock frequency
// *lower division ratios make conversion go faster
// *higher division ratios make conversions more accurate
#define ADC_PRESCALE_DIV2 0x00 ///< 0x01,0x00 -> CPU clk/2
#define ADC_PRESCALE_DIV4 0x02 ///< 0x02 -> CPU clk/4
#define ADC_PRESCALE_DIV8 0x03 ///< 0x03 -> CPU clk/8
#define ADC_PRESCALE_DIV16 0x04 ///< 0x04 -> CPU clk/16
#define ADC_PRESCALE_DIV32 0x05 ///< 0x05 -> CPU clk/32
#define ADC_PRESCALE_DIV64 0x06 ///< 0x06 -> CPU clk/64
#define ADC_PRESCALE_DIV128 0x07 ///< 0x07 -> CPU clk/128
// default value
#define ADC_PRESCALE ADC_PRESCALE_DIV64
// do not change the mask value
#define ADC_PRESCALE_MASK 0x07
// A2D voltage reference select
// *this determines what is used as the
// full-scale voltage point for A2D conversions
#define ADC_REFERENCE_AREF 0x00 ///< 0x00 -> AREF pin, internal VREF turned off
#define ADC_REFERENCE_AVCC 0x01 ///< 0x01 -> AVCC pin, internal VREF turned off
#define ADC_REFERENCE_RSVD 0x02 ///< 0x02 -> Reserved
#define ADC_REFERENCE_256V 0x03 ///< 0x03 -> Internal 2.56V VREF
// default value
#define ADC_REFERENCE ADC_REFERENCE_AVCC
// do not change the mask value
#define ADC_REFERENCE_MASK 0xC0
// bit mask for A2D channel multiplexer
#define ADC_MUX_MASK 0x1F
// channel defines (for reference and use in code)
// these channels supported by all AVRs with A2D
#define ADC_CH_ADC0 0x00
#define ADC_CH_ADC1 0x01
#define ADC_CH_ADC2 0x02
#define ADC_CH_ADC3 0x03
#define ADC_CH_ADC4 0x04
#define ADC_CH_ADC5 0x05
#define ADC_CH_ADC6 0x06
#define ADC_CH_ADC7 0x07
#define ADC_CH_122V 0x1E ///< 1.22V voltage reference
#define ADC_CH_AGND 0x1F ///< AGND
// these channels supported only in ATmega128
// differential with gain
#define ADC_CH_0_0_DIFF10X 0x08
#define ADC_CH_1_0_DIFF10X 0x09
#define ADC_CH_0_0_DIFF200X 0x0A
#define ADC_CH_1_0_DIFF200X 0x0B
#define ADC_CH_2_2_DIFF10X 0x0C
#define ADC_CH_3_2_DIFF10X 0x0D
#define ADC_CH_2_2_DIFF200X 0x0E
#define ADC_CH_3_2_DIFF200X 0x0F
// differential
#define ADC_CH_0_1_DIFF1X 0x10
#define ADC_CH_1_1_DIFF1X 0x11
#define ADC_CH_2_1_DIFF1X 0x12
#define ADC_CH_3_1_DIFF1X 0x13
#define ADC_CH_4_1_DIFF1X 0x14
#define ADC_CH_5_1_DIFF1X 0x15
#define ADC_CH_6_1_DIFF1X 0x16
#define ADC_CH_7_1_DIFF1X 0x17
#define ADC_CH_0_2_DIFF1X 0x18
#define ADC_CH_1_2_DIFF1X 0x19
#define ADC_CH_2_2_DIFF1X 0x1A
#define ADC_CH_3_2_DIFF1X 0x1B
#define ADC_CH_4_2_DIFF1X 0x1C
#define ADC_CH_5_2_DIFF1X 0x1D
// compatibility for new Mega processors
// ADCSR hack apparently no longer necessary in new AVR-GCC
#ifdef ADCSRA
#ifndef ADCSR
#define ADCSR ADCSRA
#endif
#endif
#ifdef ADATE
#define ADFR ADATE
#endif
// function prototypes
//! Initializes the A/D converter
// (turns ADC on and prepares it for use)
void a2dInit(void);
//! Turn off A/D converter
void a2dOff(void);
//! sets the division ratio of the A/D converter clock
// this function is automatically called from a2dInit()
// with a default value
void a2dSetPrescaler(unsigned char prescale);
//! configures which voltage reference the A/D converter uses
// this function is automatically called from a2dInit()
// with a default value
void a2dSetReference(unsigned char ref);
//! sets the a2d input channel
void a2dSetChannel(unsigned char ch);
//! start a conversion on the current a2d input channel
void a2dStartConvert(void);
//! return TRUE if conversion is complete
u08 a2dIsComplete(void);
//! starts a conversion on A/D channel# ch,
// returns the 10-bit value of the conversion when it is finished
unsigned short a2dConvert10bit(unsigned char ch);
//! starts a conversion on A/D channel# ch,
// returns the 8-bit value of the conversion when it is finished
unsigned char a2dConvert8bit(unsigned char ch);
#endif

View File

@ -1,93 +0,0 @@
/*! \file ads7828.c \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */
//*****************************************************************************
//
// File Name : 'ads7828.c'
// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.02.10
// Revised : 2004.02.19
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "i2c.h"
#include "ads7828.h"
// global variables
u08 Ads7282RefMode;
// Functions
u08 ads7828Init(u08 i2cAddr)
{
u08 channel = 0x80;
// setup default A/D voltage reference
ads7828SetReference(0);
// issue a convserion to test chip presence
// return TRUE if chip detected
// return FALSE if chip does not respond
return (i2cMasterSendNI(i2cAddr, 1, &channel) == I2C_OK);
}
u16 ads7828Convert(u08 i2cAddr, u08 channel)
{
// re-order channel bits for
// logical single-ended channel selection
// channel bit0 -> C2
// channel bit1 -> C0
// channel bit2 -> C1
channel = (((channel>>1) | (channel&0x01)<<2)<<4) | ADS7828_CMD_SD;
// do conversion
return ads7828ConvertRaw(i2cAddr, channel);
}
u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel)
{
// clear single-ended channel bit
channel = (channel&0x07)<<4;
// do conversion
return ads7828ConvertRaw(i2cAddr, channel);
}
u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel)
{
u08 buffer[2];
// combine raw channel and reference bits
channel &= 0xF0;
channel |= Ads7282RefMode;
// start conversion on requested channel
i2cMasterSendNI(i2cAddr, 1, &channel);
// retrieve conversion result
i2cMasterReceiveNI(i2cAddr, 2, buffer);
// pack bytes and return result
return ((buffer[0]<<8) | buffer[1]);
}
void ads7828SetReference(u08 ref)
{
if(ref)
{
// use internal reference
Ads7282RefMode = ADS7828_CMD_PDMODE2;
}
else
{
// use external reference
Ads7282RefMode = ADS7828_CMD_PDMODE0;
}
}

View File

@ -1,76 +0,0 @@
/*! \file ads7828.h \brief TI ADS7828 12-bit 8ch A/D Converter Driver Library. */
//*****************************************************************************
//
// File Name : 'ads7828.h'
// Title : TI ADS7828 12-bit 8ch A/D Converter Driver Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.02.10
// Revised : 2004.02.19
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef ADS7828_H
#define ADS7828_H
#include "global.h"
// constants/macros/typdefs
#define ADS7828_I2C_ADDR 0x90 //< Base I2C address of ADS7828 devices
// command register bit defines
#define ADS7828_CMD_PD0 0x04 //< ADS7828 Power-down bit 0
#define ADS7828_CMD_PD1 0x08 //< ADS7828 Power-down bit 1
#define ADS7828_CMD_C0 0x10 //< ADS7828 Channel Select bit 0
#define ADS7828_CMD_C1 0x20 //< ADS7828 Channel Select bit 1
#define ADS7828_CMD_C2 0x40 //< ADS7828 Channel Select bit 2
#define ADS7828_CMD_SD 0x80 //< ADS7828 Single-ended/Differential Select bit
// single-ended channel order defines
#define ADS7828_CMD_CH0 0x00 //< ADS7828 Convert Channel 0
#define ADS7828_CMD_CH1 0x04 //< ADS7828 Convert Channel 1
#define ADS7828_CMD_CH2 0x01 //< ADS7828 Convert Channel 2
#define ADS7828_CMD_CH3 0x05 //< ADS7828 Convert Channel 3
#define ADS7828_CMD_CH4 0x02 //< ADS7828 Convert Channel 4
#define ADS7828_CMD_CH5 0x06 //< ADS7828 Convert Channel 5
#define ADS7828_CMD_CH6 0x03 //< ADS7828 Convert Channel 6
#define ADS7828_CMD_CH7 0x07 //< ADS7828 Convert Channel 7
// power-down mode defines
#define ADS7828_CMD_PDMODE0 0x00 //< ADS7828 Power-down Mode 0
#define ADS7828_CMD_PDMODE1 0x04 //< ADS7828 Power-down Mode 1
#define ADS7828_CMD_PDMODE2 0x08 //< ADS7828 Power-down Mode 2
#define ADS7828_CMD_PDMODE3 0x0C //< ADS7828 Power-down Mode 3
// functions
//! Initialize the ADS7828 chip
// returns:
// TRUE if successful
// FALSE if unsuccessful (chip not present)
u08 ads7828Init(u08 i2cAddr);
//! Set the voltage reference to use for A/D conversion
// ref = 0 => External reference voltage on Ref pin
// ref = 1 => Internal 2.5V reference voltage (Ref pin left open)
void ads7828SetReference(u08 ref);
//! Begin single-ended conversion on given logical channel#, and return result
u16 ads7828Convert(u08 i2cAddr, u08 channel);
//! Begin differential conversion on given channel pair, and return result
u16 ads7828ConvertDiff(u08 i2cAddr, u08 channel);
//! Begin conversion on given raw channel#, and return result
u16 ads7828ConvertRaw(u08 i2cAddr, u08 channel);
#endif

View File

@ -1,606 +0,0 @@
/*! \file ata.c \brief IDE-ATA hard disk interface driver. */
//*****************************************************************************
//
// File Name : 'ata.c'
// Title : IDE-ATA interface driver for hard disks
// Author : Pascal Stang
// Date : 11/22/2000
// Revised : 4/19/2003
// Version : 0.3
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
// #include <stdio.h>
#endif
#include "global.h"
#include "timer.h"
#include "rprintf.h"
#include "ata.h"
//#define DEBUG_ATA 1
// global variables
// drive information
typeDriveInfo ataDriveInfo;
void ataInit(void)
{
}
void ataDriveInit(void)
{
u08 i;
unsigned char* buffer = (unsigned char*) SECTOR_BUFFER_ADDR;
// read drive identity
rprintfProgStrM("\r\nScanning IDE interface...\r\n");
// Wait for drive to be ready
ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// issue identify command
ataWriteByte(ATA_REG_CMDSTATUS1, 0xEC);
// wait for drive to request data transfer
ataStatusWait(ATA_SR_DRQ, ATA_SR_DRQ);
timerPause(200);
// read in the data
ataReadDataBuffer(buffer, 512);
// set local drive info parameters
ataDriveInfo.cylinders = *( ((unsigned int*) buffer) + ATA_IDENT_CYLINDERS );
ataDriveInfo.heads = *( ((unsigned int*) buffer) + ATA_IDENT_HEADS );
ataDriveInfo.sectors = *( ((unsigned int*) buffer) + ATA_IDENT_SECTORS );
ataDriveInfo.LBAsupport = *( ((unsigned int*) buffer) + ATA_IDENT_FIELDVALID );
ataDriveInfo.sizeinsectors = *( (unsigned long*) (buffer + ATA_IDENT_LBASECTORS*2) );
// copy model string
for(i=0; i<40; i+=2)
{
// correct for byte order
ataDriveInfo.model[i ] = buffer[(ATA_IDENT_MODEL*2) + i + 1];
ataDriveInfo.model[i+1] = buffer[(ATA_IDENT_MODEL*2) + i ];
}
// terminate string
ataDriveInfo.model[40] = 0;
// process and print info
if(ataDriveInfo.LBAsupport)
{
// LBA support
rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) );
rprintf("LBA mode -- MODEL: ");
}
else
{
// CHS, no LBA support
// calculate drive size
ataDriveInfo.sizeinsectors = (unsigned long) ataDriveInfo.cylinders*
ataDriveInfo.heads*ataDriveInfo.sectors;
rprintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) );
rprintf("CHS mode C=%d H=%d S=%d -- MODEL: ", ataDriveInfo.cylinders, ataDriveInfo.heads, ataDriveInfo.sectors );
}
// print model information
rprintfStr(ataDriveInfo.model); rprintfCRLF();
// initialize local disk parameters
//ataDriveInfo.cylinders = ATA_DISKPARM_CLYS;
//ataDriveInfo.heads = ATA_DISKPARM_HEADS;
//ataDriveInfo.sectors = ATA_DISKPARM_SECTORS;
}
void ataDiskErr(void)
{
unsigned char b;
b = ataReadByte(ATA_REG_ERROR);
rprintfProgStrM("ATA Error: ");
rprintfu08(b);
rprintfCRLF();
}
void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout)
{
// select drive
ataDriveSelect(DriveNo);
// Wait for drive to be ready
ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// set mode
switch(mode)
{
case ATA_DISKMODE_SPINDOWN: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINDOWN); break;
case ATA_DISKMODE_SPINUP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SPINUP); break;
case ATA_DISKMODE_SETTIMEOUT:
ataWriteByte(ATA_REG_SECCOUNT, timeout);
ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_IDLE_5SU);
break;
case ATA_DISKMODE_SLEEP: ataWriteByte(ATA_REG_CMDSTATUS1, ATA_CMD_SLEEP); break;
default:
break;
}
}
void ataPrintSector( u08 *Buffer)
{
u08 i;
u16 j;
u08 *buf;
u08 s;
buf = Buffer;
// print the low order address indicies
rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n");
rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n");
// print the data
for(j=0; j<0x20; j++)
{
// print the high order address index for this line
rprintfu16(j<<4);
rprintfProgStrM(" ");
// print the hex data
for(i=0; i<0x10; i++)
{
rprintfu08(buf[(j<<4)+i]);
rprintfProgStrM(" ");
}
// leave some space
rprintfProgStrM(" ");
// print the ascii data
for(i=0; i<0x10; i++)
{
s = buf[(j<<4)+i];
// make sure character is printable
if(s >= 0x20)
{
rprintfChar(s);
}
else
{
rprintfChar(0x20);
}
}
rprintfCRLF();
}
}
void ataReadDataBuffer(u08 *Buffer, u16 numBytes)
{
unsigned int i;
//sbi(MCUCR, SRW); // enable RAM waitstate
// read data from drive
for (i=0; i<(numBytes/16); i++)
{
// optimize by reading 16 bytes in-line before looping
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
}
//cbi(MCUCR, SRW); // disable RAM waitstate
}
void ataWriteDataBuffer(u08 *Buffer, u16 numBytes)
{
register unsigned char temp;
unsigned int i;
//sbi(MCUCR, SRW); // enable RAM waitstate
// write data to drive
for (i=0; i<(numBytes/16); i++)
{
// optimize by writing 16 bytes in-line before looping
// keep byte order correct by using temp register
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
}
//cbi(MCUCR, SRW); // disable RAM waitstate
}
u08 ataStatusWait(u08 mask, u08 waitStatus)
{
register u08 status;
delay(100);
// wait for desired status
while( ((status = ataReadByte(ATA_REG_CMDSTATUS1)) & mask) == waitStatus );
return status;
}
unsigned char ataReadSectorsCHS( unsigned char Drive,
unsigned char Head,
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned char temp;
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// Prepare parameters...
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track
ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track
ataWriteByte(ATA_REG_STARTSEC, Sector); // sector
ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
// Issue read sector command...
ataWriteByte(ATA_REG_CMDSTATUS1, 0x21);
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
if (temp & ATA_SR_ERR)
{
rprintfProgStrM("RD ERR\r\n");
return 1;
}
// Wait for drive to request data transfer
ataStatusWait(ATA_SR_DRQ, 0);
// read data from drive
ataReadDataBuffer(Buffer, 512*numsectors);
// Return the error bit from the status register...
temp = ataReadByte(ATA_REG_CMDSTATUS1); // read status register
return (temp & ATA_SR_ERR) ? 1:0;
}
unsigned char ataWriteSectorsCHS(unsigned char Drive,
unsigned char Head,
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned char temp;
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// Prepare parameters...
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track
ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track
ataWriteByte(ATA_REG_STARTSEC, Sector); // sector
ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
// Issue write sector command
ataWriteByte(ATA_REG_CMDSTATUS1, 0x31);
//delay(100);
// Wait for drive to request data transfer
ataStatusWait(ATA_SR_DRQ, 0);
// write data to drive
ataWriteDataBuffer(Buffer, 512*numsectors);
// Wait for drive to finish write
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// check for errors
if (temp & ATA_SR_ERR)
{
rprintfProgStrM("WR ERR\r\n");
return 1;
}
// Return the error bit from the status register...
return (temp & ATA_SR_ERR) ? 1:0;
}
unsigned char ataReadSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
rprintfProgStrM("ATA LBA read ");
rprintfu32(lba); rprintfProgStrM(" ");
rprintfu16(numsectors); rprintfProgStrM(" ");
rprintfu16((unsigned int)Buffer);
rprintfCRLF();
#endif
sect = (int) ( lba & 0x000000ffL );
lba = lba >> 8;
cyl = (int) ( lba & 0x0000ffff );
lba = lba >> 16;
head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;
temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataWriteSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
#ifdef DEBUG_ATA
rprintfProgStrM("ATA LBA write ");
rprintfu32(lba); rprintfProgStrM(" ");
rprintfu16(numsectors); rprintfProgStrM(" ");
rprintfu16((unsigned int)Buffer);
rprintfCRLF();
#endif
sect = (int) ( lba & 0x000000ffL );
lba = lba >> 8;
cyl = (int) ( lba & 0x0000ffff );
lba = lba >> 16;
head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;
temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataReadSectors( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
// check if drive supports native LBA mode
if(ataDriveInfo.LBAsupport)
{
// drive supports using native LBA
temp = ataReadSectorsLBA(Drive, lba, numsectors, Buffer);
}
else
{
// drive required CHS access
#ifdef DEBUG_ATA
// do this defore destroying lba
rprintfProgStrM("ATA LBA for CHS read: ");
rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" ");
#endif
// convert LBA to pseudo CHS
// remember to offset the sector count by one
sect = (u08) (lba % ataDriveInfo.sectors)+1;
lba = lba / ataDriveInfo.sectors;
head = (u08) (lba % ataDriveInfo.heads);
lba = lba / ataDriveInfo.heads;
cyl = (u16) lba;
#ifdef DEBUG_ATA
rprintfProgStrM("C:H:S=");
rprintfu16(cyl); rprintfProgStrM(":");
rprintfu08(head); rprintfProgStrM(":");
rprintfu08(sect); rprintfCRLF();
#endif
temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
}
if(temp)
ataDiskErr();
return temp;
}
unsigned char ataWriteSectors(unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned int cyl, head, sect;
unsigned char temp;
// check if drive supports native LBA mode
if(ataDriveInfo.LBAsupport)
{
// drive supports using native LBA
temp = ataWriteSectorsLBA(Drive, lba, numsectors, Buffer);
}
else
{
// drive required CHS access
#ifdef DEBUG_ATA
// do this defore destroying lba
rprintfProgStrM("ATA LBA for CHS write: ");
rprintfProgStrM("LBA="); rprintfu32(lba); rprintfProgStrM(" ");
#endif
// convert LBA to pseudo CHS
// remember to offset the sector count by one
sect = (u08) (lba % ataDriveInfo.sectors)+1;
lba = lba / ataDriveInfo.sectors;
head = (u08) (lba % ataDriveInfo.heads);
lba = lba / ataDriveInfo.heads;
cyl = (u16) lba;
#ifdef DEBUG_ATA
rprintfProgStrM("C:H:S=");
rprintfu16(cyl); rprintfProgStrM(":");
rprintfu08(head); rprintfProgStrM(":");
rprintfu08(sect); rprintfCRLF();
#endif
temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
}
if(temp)
ataDiskErr();
return temp;
}
void ataDriveSelect(u08 DriveNo)
{
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(DriveNo ? 0x10:00)); // Drive selection
}
//----------------------------------------------------------------------------
// Set drive mode (STANDBY, IDLE)
//----------------------------------------------------------------------------
/*#define STANDBY 0
#define IDLE 1
#define SLEEP 2
*/
/*
unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown)
{
WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
WriteBYTE(CMD, 2, (PwrDown ? 0x01:0x00)); // Enable automatic power down
switch (Mode)
{
case STANDBY: WriteBYTE(CMD,7, 0xE2); break;
case IDLE: WriteBYTE(CMD,7, 0xE3); break;
// NOTE: To recover from sleep, either issue a soft or hardware reset !
// (But not on all drives, f.ex seagate ST3655A it's not nessecary to reset
// but only to go in Idle mode, But on a Conner CFA170A it's nessecary with
// a reset)
case SLEEP: WriteBYTE(CMD,7, 0xE6); break;
}
Timer10mSec=10000;
while ((ReadBYTE(CMD,7) & 0xC0)!=0x40 && Timer10mSec); // Wait for DRDY & NOT BUSY
if (Timer10mSec==0) return 0xFF; // or timeout
// Return the error register...
return ReadBYTE(CMD, 1);
}
*/
u08 ataReadByte(u08 reg)
{
register u08 ret;
//sbi(MCUCR, SRW); // enable RAM waitstate
ret = *((volatile unsigned char*) ATA_REG_BASE + reg);
//cbi(MCUCR, SRW); // disable RAM waitstate
return ret;
}
void ataWriteByte(u08 reg, u08 data)
{
//sbi(MCUCR, SRW); // enable RAM waitstate
*((volatile unsigned char*) ATA_REG_BASE + reg) = data;
//cbi(MCUCR, SRW); // disable RAM waitstate
}
void ataShowRegisters(unsigned char DriveNo)
{
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
rprintfProgStrM("R0: DATALOW = 0x"); rprintfu08(ataReadByte(ATA_REG_DATAL )); rprintfProgStrM(" \r\n");
rprintfProgStrM("R1: ERROR = 0x"); rprintfu08(ataReadByte(ATA_REG_ERROR )); rprintfProgStrM(" \r\n");
rprintfProgStrM("R2: SECT CNT = 0x"); rprintfu08(ataReadByte(ATA_REG_SECCOUNT)); rprintfProgStrM(" \r\n");
rprintfProgStrM("R3: SECT NUM = 0x"); rprintfu08(ataReadByte(ATA_REG_STARTSEC)); rprintfProgStrM(" \r\n");
rprintfProgStrM("R4: CYL LOW = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLLO )); rprintfProgStrM(" \r\n");
rprintfProgStrM("R5: CYL HIGH = 0x"); rprintfu08(ataReadByte(ATA_REG_CYLHI )); rprintfProgStrM(" \r\n");
rprintfProgStrM("R6: HEAD/DEV = 0x"); rprintfu08(ataReadByte(ATA_REG_HDDEVSEL)); rprintfProgStrM(" \r\n");
rprintfProgStrM("R7: CMD/STA = 0x"); rprintfu08(ataReadByte(ATA_REG_CMDSTATUS1)); rprintfProgStrM("\r\n");
}
unsigned char ataSWReset(void)
{
ataWriteByte(ATA_REG_HDDEVSEL, 0x06); // SRST and nIEN bits
delay(10); // 10uS delay
ataWriteByte(ATA_REG_HDDEVSEL, 0x02); // nIEN bits
delay(10); // 10 uS delay
while( (ataReadByte(ATA_REG_CMDSTATUS1) & 0xC0) != 0x40 ); // Wait for DRDY and not BSY
return ataReadByte(ATA_REG_CMDSTATUS1) + ataReadByte(ATA_REG_ERROR);
}
/*
unsigned char ATA_Idle(unsigned char Drive)
{
WriteBYTE(CMD, 6, 0xA0 + (Drive ? 0x10:0x00)); // Select drive
WriteBYTE(CMD,7, 0xE1);
while ((ReadBYTE(CMD,7) & 0xC0)!=0x40); // Wait for DRDY & NOT BUSY
// Return the error register...
return ReadBYTE(CMD, 1);
}
*/

View File

@ -1,182 +0,0 @@
/*! \file ata.h \brief IDE-ATA hard disk interface driver. */
//*****************************************************************************
//
// File Name : 'ata.h'
// Title : IDE-ATA interface driver for hard disks
// Author : Pascal Stang
// Date : 11/22/2000
// Revised : 12/29/2000
// Version : 0.3
// Target MCU : ATmega103 (should work for Atmel AVR Series)
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef ATA_H
#define ATA_H
#include "global.h"
#include "ataconf.h"
// constants
#define DRIVE0 0
#define STANDBY 0
#define SLEEP 1
#define IDLE 2
// ATA status register bits
#define ATA_SR_BSY 0x80
#define ATA_SR_DRDY 0x40
#define ATA_SR_DF 0x20
#define ATA_SR_DSC 0x10
#define ATA_SR_DRQ 0x08
#define ATA_SR_CORR 0x04
#define ATA_SR_IDX 0x02
#define ATA_SR_ERR 0x01
// ATA error register bits
#define ATA_ER_UNC 0x40
#define ATA_ER_MC 0x20
#define ATA_ER_IDNF 0x10
#define ATA_ER_MCR 0x08
#define ATA_ER_ABRT 0x04
#define ATA_ER_TK0NF 0x02
#define ATA_ER_AMNF 0x01
// ATA head register bits
#define ATA_HEAD_USE_LBA 0x40
/*
// ATA registers
#define ATA_REG_BASE 0x8000
#define ATA_REG_DATAL 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_SECCOUNT 0x02
#define ATA_REG_STARTSEC 0x03
#define ATA_REG_CYLLO 0x04
#define ATA_REG_CYLHI 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_CMDSTATUS1 0x07
#define ATA_REG_CMDSTATUS2 0x08
#define ATA_REG_ACTSTATUS 0x09
#define ATA_REG_DATAH 0x10
*/
// ATA commands
#define ATA_CMD_READ 0x20
#define ATA_CMD_READNR 0x21
#define ATA_CMD_WRITE 0x30
#define ATA_CMD_WRITENR 0x31
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_CMD_RECALIBRATE 0x10
#define ATA_CMD_SPINDOWN 0xE0 // spin down disk immediately
#define ATA_CMD_SPINUP 0xE1 // spin up disk immediately
#define ATA_CMD_STANDBY_5SU 0xE2 // spin down disk and set auto-power-down timer (sectorcount*5sec)
#define ATA_CMD_IDLE_5SU 0xE3 // keep disk spinning and set auto-power-down timer (sectorcount*5sec)
#define ATA_CMD_SLEEP 0xE6 // sleep disk (wakeup only on HW or SW reset)
#define ATA_CMD_STANDBY_01SU 0xF2 // spin down disk and set auto-power-down timer (sectorcount*0.1sec)
#define ATA_CMD_IDLE_01SU 0xF3 // keep disk spinning and set auto-power-down timer (sectorcount*0.1sec)
// ATA CHS disk parameters (examples, now we autodetect)
#define ATA_DISKPARM_CLYS 0x03A6 // number of cylinders per platter
#define ATA_DISKPARM_HEADS 0x10 // number of heads (usable plater sides)
#define ATA_DISKPARM_SECTORS 0x11 // number of sectors per head per cylinder
// ATA Identity fields
// all offsets refer to word offset (2 byte increments)
#define ATA_IDENT_DEVICETYPE 0 // specifies ATA/ATAPI, removable/non-removable
#define ATA_IDENT_CYLINDERS 1 // number of logical cylinders
#define ATA_IDENT_HEADS 3 // number of logical heads
#define ATA_IDENT_SECTORS 6 // number of sectors per track
#define ATA_IDENT_SERIAL 10 // drive model name (20 characters)
#define ATA_IDENT_MODEL 27 // drive model name (40 characters)
#define ATA_IDENT_FIELDVALID 53 // indicates field validity of higher words (bit0: words54-58, bit1: words 64-70)
#define ATA_IDENT_LBASECTORS 60 // number of sectors in LBA translation mode
// drive mode defines (for ataSetDrivePowerMode() )
#define ATA_DISKMODE_SPINDOWN 0
#define ATA_DISKMODE_SPINUP 1
#define ATA_DISKMODE_SETTIMEOUT 2
#define ATA_DISKMODE_SLEEP 3
// typedefs
// drive info structure
typedef struct
{
unsigned int cylinders;
unsigned char heads;
unsigned char sectors;
unsigned long sizeinsectors;
unsigned char LBAsupport;
char model[41];
} typeDriveInfo;
// Prototypes
void ataInit(void);
void ataDriveInit(void);
void ataDriveSelect(u08 DriveNo);
void ataSetDrivePowerMode(u08 DriveNo, u08 mode, u08 timeout);
u08 ataReadByte(u08 reg);
void ataWriteByte(u08 reg, u08 data);
void ataShowRegisters(unsigned char DriveNo);
u08 ataSWReset(void);
void ataDiskErr(void);
void ataPrintSector( u08 *Buffer);
void ataReadDataBuffer(u08 *Buffer, u16 numBytes);
void ataWriteDataBuffer(u08 *Buffer, u16 numBytes);
u08 ataStatusWait(u08 mask, u08 waitStatus);
// read and write routines for CHS based drives
unsigned char ataReadSectorsCHS( unsigned char Drive,
unsigned char Head,
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer);
unsigned char ataWriteSectorsCHS( unsigned char Drive,
unsigned char Head,
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer);
// read and write routines for LBA based drives
unsigned char ataReadSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer);
unsigned char ataWriteSectorsLBA( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer);
// generic read and write routines using LBA
// uses native or translated LBA addressing
// given autodetected drive type
unsigned char ataReadSectors( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer);
unsigned char ataWriteSectors( unsigned char Drive,
unsigned long lba,
unsigned int numsectors,
unsigned char *Buffer);
//unsigned char IdentifyDrive(unsigned char DriveNo, unsigned char *Buffer, tdefDriveInfo *DriveInfo);
//unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown);
//unsigned char ATA_Idle(unsigned char Drive);
#endif

View File

@ -1,77 +0,0 @@
/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */
//*****************************************************************************
//
// File Name : 'avrlibdefs.h'
// Title : AVRlib global defines and macros include file
// Author : Pascal Stang
// Created : 7/12/2001
// Revised : 9/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This include file is designed to contain items useful to all
// code files and projects, regardless of specific implementation.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef AVRLIBDEFS_H
#define AVRLIBDEFS_H
// Code compatibility to new AVR-libc
// outb(), inb(), BV(), sbi(), cbi(), sei(), cli()
#ifndef outb
#define outb(addr, data) addr = (data)
#endif
#ifndef inb
#define inb(addr) (addr)
#endif
#ifndef BV
#define BV(bit) (1<<(bit))
#endif
#ifndef cbi
#define cbi(reg,bit) reg &= ~(BV(bit))
#endif
#ifndef sbi
#define sbi(reg,bit) reg |= (BV(bit))
#endif
#ifndef cli
#define cli() __asm__ __volatile__ ("cli" ::)
#endif
#ifndef sei
#define sei() __asm__ __volatile__ ("sei" ::)
#endif
// support for individual port pin naming in the mega128
// see port128.h for details
#ifdef __AVR_ATmega128__
// not currently necessary due to inclusion
// of these defines in newest AVR-GCC
// do a quick test to see if include is needed
#ifndef PD0
#include "port128.h"
#endif
#endif
// use this for packed structures
// (this is seldom necessary on an 8-bit architecture like AVR,
// but can assist in code portability to AVR)
#define GNUC_PACKED __attribute__((packed))
// port address helpers
#define DDR(x) ((x)-1) // address of data direction register of port x
#define PIN(x) ((x)-2) // address of input register of port x
// MIN/MAX/ABS macros
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a>b)?(a):(b))
#define ABS(x) ((x>0)?(x):(-x))
// constants
#define PI 3.14159265359
#endif

View File

@ -1,84 +0,0 @@
/*! \file avrlibtypes.h \brief AVRlib global types and typedefines. */
//*****************************************************************************
//
// File Name : 'avrlibtypes.h'
// Title : AVRlib global types and typedefines include file
// Author : Pascal Stang
// Created : 7/12/2001
// Revised : 9/30/2002
// Version : 1.0
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : Type-defines required and used by AVRlib. Most types are also
// generally useful.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef AVRLIBTYPES_H
#define AVRLIBTYPES_H
#ifndef WIN32
// true/false defines
#define FALSE 0
#define TRUE -1
#endif
// datatype definitions macros
typedef unsigned char u08;
typedef signed char s08;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned long long u64;
typedef signed long long s64;
/* use inttypes.h instead
// C99 standard integer type definitions
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
typedef unsigned long uint64_t;
typedef signed long int64_t;
*/
// maximum value that can be held
// by unsigned data types (8,16,32bits)
#define MAX_U08 255
#define MAX_U16 65535
#define MAX_U32 4294967295
// maximum values that can be held
// by signed data types (8,16,32bits)
#define MIN_S08 -128
#define MAX_S08 127
#define MIN_S16 -32768
#define MAX_S16 32767
#define MIN_S32 -2147483648
#define MAX_S32 2147483647
#ifndef WIN32
// more type redefinitions
typedef unsigned char BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
typedef char CHAR;
typedef int INT;
typedef long LONG;
#endif
#endif

View File

@ -1,131 +0,0 @@
/*! \file bitbuf.c \brief Multipurpose bit buffer structure and methods. */
//*****************************************************************************
//
// File Name : 'bitbuf.c'
// Title : Multipurpose bit buffer structure and methods
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 7/10/2002
// Revised : 7/10/2002
// Version : 0.5
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "bitbuf.h"
// global variables
//! Initialize the bit buffer
// sets the start location and size of the buffer in memory
void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize)
{
// set start pointer of the buffer
bitBuffer->dataptr = start;
bitBuffer->size = bytesize;
// initialize indexing and length
bitBuffer->dataindex = 0;
bitbufFlush(bitBuffer);
}
// access routines
//! Get a bit from the current position in the buffer
// returns the bit at the current position in the buffer
// and increments the bit position
unsigned char bitbufGet(BitBuf* bitBuffer)
{
unsigned char byte;
unsigned char bit;
// get current working byte
byte = bitBuffer->dataptr[bitBuffer->bytePos];
// read data bit
bit = (byte & (1<<bitBuffer->bitPos))?(1):(0);
// increment bit counter
if(bitBuffer->bitPos < 7)
{
bitBuffer->bitPos++;
}
else
{
// increment byte counter
bitBuffer->bitPos = 0;
bitBuffer->bytePos++;
}
// return bit value
return bit;
}
//! Get a bit from a given index into the buffer
// returns the bit at position [bitIndex] in the buffer
unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex)
{
// return bit at index in buffer
return (bitBuffer->dataptr[bitIndex>>3] & (1<<(bitIndex & 0x07)))?(1):(0);
}
//! Store a bit at the current position in the buffer
// stores the bit at the current position in the buffer
// and increments the bit position
void bitbufStore(BitBuf* bitBuffer, unsigned char bit)
{
unsigned char byte;
// get current working byte
byte = bitBuffer->dataptr[bitBuffer->bytePos];
// apply data bit
if(bit)
byte |= (1<<bitBuffer->bitPos);
else
byte &= ~(1<<bitBuffer->bitPos);
// store data
bitBuffer->dataptr[bitBuffer->bytePos] = byte;
bitBuffer->datalength++;
// increment bit counter
if(bitBuffer->bitPos < 7)
{
bitBuffer->bitPos++;
}
else
{
// increment byte counter
bitBuffer->bitPos = 0;
bitBuffer->bytePos++;
}
}
void bitbufReset(BitBuf* bitBuffer)
{
// reset counters
bitBuffer->bytePos = 0;
bitBuffer->bitPos = 0;
}
void bitbufFlush(BitBuf* bitBuffer)
{
// flush contents of the buffer
bitBuffer->datalength = 0;
// reset indexing
bitbufReset(bitBuffer);
}
unsigned short bitbufGetDataLength(BitBuf* bitBuffer)
{
return bitBuffer->datalength;
}
/*
unsigned char bitbufIsNotFull(cBuffer* buffer)
{
// check to see if the buffer has room
// return true if there is room
return (buffer->datalength < buffer->size);
}
*/

View File

@ -1,62 +0,0 @@
/*! \file bitbuf.h \brief Multipurpose bit buffer structure and methods. */
//*****************************************************************************
//
// File Name : 'bitbuf.c'
// Title : Multipurpose bit buffer structure and methods
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 7/10/2002
// Revised : 7/10/2002
// Version : 0.5
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef BITBUF_H
#define BITBUF_H
// structure/typdefs
// the BitBuffer structure
typedef struct struct_BitBuf
{
unsigned char *dataptr; // the physical memory address where the buffer is stored
unsigned short size; // the allocated byte size of the buffer
unsigned short bytePos; // current byte position
unsigned short bitPos; // current bit position
unsigned short datalength; // the length of the data (in bits) currently in the buffer
unsigned short dataindex; // the index (in bits) into the buffer where the data starts
} BitBuf;
// function prototypes
//! initialize a buffer to start at a given address and have given size
void bitbufInit(BitBuf* bitBuffer, unsigned char *start, unsigned short bytesize);
//! get the bit at the current position in the buffer
unsigned char bitbufGet(BitBuf* bitBuffer);
//! get a bit at the specified index in the buffer (kind of like array access)
// ** note: this does not remove/delete the bit that was read
unsigned char bitbufGetAtIndex(BitBuf* bitBuffer, unsigned short bitIndex);
//! store a bit at the current position in the buffer
void bitbufStore(BitBuf* bitBuffer, unsigned char bit);
//! return the number of bits in the buffer
unsigned short bitbufGetDataLength(BitBuf* bitBuffer);
// check if the buffer is full/not full (returns non-zero value if not full)
//unsigned char bitbufIsNotFull(cBuffer* buffer);
//! resets the read/write position of the buffer to beginning
void bitbufReset(BitBuf* bitBuffer);
//! flush (clear) the contents of the buffer
void bitbufFlush(BitBuf* bitBuffer);
#endif

View File

@ -1,110 +0,0 @@
/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */
//*****************************************************************************
//
// File Name : 'buffer.c'
// Title : Multipurpose byte buffer structure and methods
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 9/23/2001
// Revised : 9/23/2001
// Version : 1.0
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "buffer.h"
// global variables
// initialization
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size)
{
// set start pointer of the buffer
buffer->dataptr = start;
buffer->size = size;
// initialize index and length
buffer->dataindex = 0;
buffer->datalength = 0;
}
// access routines
unsigned char bufferGetFromFront(cBuffer* buffer)
{
unsigned char data = 0;
// check to see if there's data in the buffer
if(buffer->datalength)
{
// get the first character from buffer
data = buffer->dataptr[buffer->dataindex];
// move index down and decrement length
buffer->dataindex++;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex %= buffer->size;
}
buffer->datalength--;
}
// return
return data;
}
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes)
{
// dump numbytes from the front of the buffer
// are we dumping less than the entire buffer?
if(numbytes < buffer->datalength)
{
// move index down by numbytes and decrement length by numbytes
buffer->dataindex += numbytes;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex %= buffer->size;
}
buffer->datalength -= numbytes;
}
else
{
// flush the whole buffer
buffer->datalength = 0;
}
}
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index)
{
// return character at index in buffer
return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)];
}
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data)
{
// make sure the buffer has room
if(buffer->datalength < buffer->size)
{
// save data byte at end of buffer
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
// increment the length
buffer->datalength++;
// return success
return -1;
}
else return 0;
}
unsigned char bufferIsNotFull(cBuffer* buffer)
{
// check to see if the buffer has room
// return true if there is room
return (buffer->datalength < buffer->size);
}
void bufferFlush(cBuffer* buffer)
{
// flush contents of the buffer
buffer->datalength = 0;
}

View File

@ -1,56 +0,0 @@
/*! \file buffer.h \brief Multipurpose byte buffer structure and methods. */
//*****************************************************************************
//
// File Name : 'buffer.h'
// Title : Multipurpose byte buffer structure and methods
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 9/23/2001
// Revised : 11/16/2002
// Version : 1.1
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef BUFFER_H
#define BUFFER_H
// structure/typdefs
// the cBuffer structure
typedef struct struct_cBuffer
{
unsigned char *dataptr; // the physical memory address where the buffer is stored
unsigned short size; // the allocated size of the buffer
unsigned short datalength; // the length of the data currently in the buffer
unsigned short dataindex; // the index into the buffer where the data starts
} cBuffer;
// function prototypes
//! initialize a buffer to start at a given address and have given size
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size);
//! get the first byte from the front of the buffer
unsigned char bufferGetFromFront(cBuffer* buffer);
//! dump (discard) the first numbytes from the front of the buffer
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes);
//! get a byte at the specified index in the buffer (kind of like array access)
// ** note: this does not remove the byte that was read from the buffer
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index);
//! add a byte to the end of the buffer
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data);
//! check if the buffer is full/not full (returns non-zero value if not full)
unsigned char bufferIsNotFull(cBuffer* buffer);
//! flush (clear) the contents of the buffer
void bufferFlush(cBuffer* buffer);
#endif

View File

@ -1,390 +0,0 @@
1 .file "buffer.c"
2 .arch atmega8
3 __SREG__ = 0x3f
4 __SP_H__ = 0x3e
5 __SP_L__ = 0x3d
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
8 .global __do_copy_data
9 .global __do_clear_bss
12 .text
13 .Ltext0:
44 .global bufferInit
46 bufferInit:
1:../avrlib/buffer.c **** /*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */
2:../avrlib/buffer.c **** //*****************************************************************************
3:../avrlib/buffer.c **** //
4:../avrlib/buffer.c **** // File Name : 'buffer.c'
5:../avrlib/buffer.c **** // Title : Multipurpose byte buffer structure and methods
6:../avrlib/buffer.c **** // Author : Pascal Stang - Copyright (C) 2001-2002
7:../avrlib/buffer.c **** // Created : 9/23/2001
8:../avrlib/buffer.c **** // Revised : 9/23/2001
9:../avrlib/buffer.c **** // Version : 1.0
10:../avrlib/buffer.c **** // Target MCU : any
11:../avrlib/buffer.c **** // Editor Tabs : 4
12:../avrlib/buffer.c **** //
13:../avrlib/buffer.c **** // This code is distributed under the GNU Public License
14:../avrlib/buffer.c **** // which can be found at http://www.gnu.org/licenses/gpl.txt
15:../avrlib/buffer.c **** //
16:../avrlib/buffer.c **** //*****************************************************************************
17:../avrlib/buffer.c ****
18:../avrlib/buffer.c **** #include "buffer.h"
19:../avrlib/buffer.c ****
20:../avrlib/buffer.c **** // global variables
21:../avrlib/buffer.c ****
22:../avrlib/buffer.c **** // initialization
23:../avrlib/buffer.c ****
24:../avrlib/buffer.c **** void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size)
25:../avrlib/buffer.c **** {
48 .LM1:
49 /* prologue: frame size=0 */
50 /* prologue end (size=0) */
51 0000 FC01 movw r30,r24
26:../avrlib/buffer.c **** // set start pointer of the buffer
27:../avrlib/buffer.c **** buffer->dataptr = start;
53 .LM2:
54 0002 6083 st Z,r22
55 0004 7183 std Z+1,r23
28:../avrlib/buffer.c **** buffer->size = size;
57 .LM3:
58 0006 4283 std Z+2,r20
59 0008 5383 std Z+3,r21
29:../avrlib/buffer.c **** // initialize index and length
30:../avrlib/buffer.c **** buffer->dataindex = 0;
61 .LM4:
62 000a 1682 std Z+6,__zero_reg__
63 000c 1782 std Z+7,__zero_reg__
31:../avrlib/buffer.c **** buffer->datalength = 0;
65 .LM5:
66 000e 1482 std Z+4,__zero_reg__
67 0010 1582 std Z+5,__zero_reg__
68 /* epilogue: frame size=0 */
69 0012 0895 ret
70 /* epilogue end (size=1) */
71 /* function bufferInit size 10 (9) */
73 .Lscope0:
77 .global bufferGetFromFront
79 bufferGetFromFront:
32:../avrlib/buffer.c **** }
33:../avrlib/buffer.c ****
34:../avrlib/buffer.c **** // access routines
35:../avrlib/buffer.c **** unsigned char bufferGetFromFront(cBuffer* buffer)
36:../avrlib/buffer.c **** {
81 .LM6:
82 /* prologue: frame size=0 */
83 0014 CF93 push r28
84 0016 DF93 push r29
85 /* prologue end (size=2) */
86 0018 EC01 movw r28,r24
37:../avrlib/buffer.c **** unsigned char data = 0;
88 .LM7:
89 001a E0E0 ldi r30,lo8(0)
38:../avrlib/buffer.c ****
39:../avrlib/buffer.c **** // check to see if there's data in the buffer
40:../avrlib/buffer.c **** if(buffer->datalength)
91 .LM8:
92 001c 2C81 ldd r18,Y+4
93 001e 3D81 ldd r19,Y+5
94 0020 2115 cp r18,__zero_reg__
95 0022 3105 cpc r19,__zero_reg__
96 0024 B1F0 breq .L3
41:../avrlib/buffer.c **** {
42:../avrlib/buffer.c **** // get the first character from buffer
43:../avrlib/buffer.c **** data = buffer->dataptr[buffer->dataindex];
98 .LM9:
99 0026 E881 ld r30,Y
100 0028 F981 ldd r31,Y+1
101 002a 8E81 ldd r24,Y+6
102 002c 9F81 ldd r25,Y+7
103 002e E80F add r30,r24
104 0030 F91F adc r31,r25
105 0032 E081 ld r30,Z
44:../avrlib/buffer.c **** // move index down and decrement length
45:../avrlib/buffer.c **** buffer->dataindex++;
107 .LM10:
108 0034 0196 adiw r24,1
109 0036 8E83 std Y+6,r24
110 0038 9F83 std Y+7,r25
46:../avrlib/buffer.c **** if(buffer->dataindex >= buffer->size)
112 .LM11:
113 003a 6A81 ldd r22,Y+2
114 003c 7B81 ldd r23,Y+3
115 003e 8617 cp r24,r22
116 0040 9707 cpc r25,r23
117 0042 18F0 brlo .L4
47:../avrlib/buffer.c **** {
48:../avrlib/buffer.c **** buffer->dataindex %= buffer->size;
119 .LM12:
120 0044 00D0 rcall __udivmodhi4
121 0046 8E83 std Y+6,r24
122 0048 9F83 std Y+7,r25
123 .L4:
49:../avrlib/buffer.c **** }
50:../avrlib/buffer.c **** buffer->datalength--;
125 .LM13:
126 004a 2150 subi r18,lo8(-(-1))
127 004c 3040 sbci r19,hi8(-(-1))
128 004e 2C83 std Y+4,r18
129 0050 3D83 std Y+5,r19
130 .L3:
51:../avrlib/buffer.c **** }
52:../avrlib/buffer.c **** // return
53:../avrlib/buffer.c **** return data;
54:../avrlib/buffer.c **** }
132 .LM14:
133 0052 8E2F mov r24,r30
134 0054 9927 clr r25
135 /* epilogue: frame size=0 */
136 0056 DF91 pop r29
137 0058 CF91 pop r28
138 005a 0895 ret
139 /* epilogue end (size=3) */
140 /* function bufferGetFromFront size 36 (31) */
145 .Lscope1:
150 .global bufferDumpFromFront
152 bufferDumpFromFront:
55:../avrlib/buffer.c ****
56:../avrlib/buffer.c **** void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes)
57:../avrlib/buffer.c **** {
154 .LM15:
155 /* prologue: frame size=0 */
156 005c CF93 push r28
157 005e DF93 push r29
158 /* prologue end (size=2) */
159 0060 FC01 movw r30,r24
160 0062 EB01 movw r28,r22
58:../avrlib/buffer.c **** // dump numbytes from the front of the buffer
59:../avrlib/buffer.c **** // are we dumping less than the entire buffer?
60:../avrlib/buffer.c **** if(numbytes < buffer->datalength)
162 .LM16:
163 0064 2481 ldd r18,Z+4
164 0066 3581 ldd r19,Z+5
165 0068 6217 cp r22,r18
166 006a 7307 cpc r23,r19
167 006c 98F4 brsh .L6
61:../avrlib/buffer.c **** {
62:../avrlib/buffer.c **** // move index down by numbytes and decrement length by numbytes
63:../avrlib/buffer.c **** buffer->dataindex += numbytes;
169 .LM17:
170 006e 8681 ldd r24,Z+6
171 0070 9781 ldd r25,Z+7
172 0072 860F add r24,r22
173 0074 971F adc r25,r23
174 0076 8683 std Z+6,r24
175 0078 9783 std Z+7,r25
64:../avrlib/buffer.c **** if(buffer->dataindex >= buffer->size)
177 .LM18:
178 007a 6281 ldd r22,Z+2
179 007c 7381 ldd r23,Z+3
180 007e 8617 cp r24,r22
181 0080 9707 cpc r25,r23
182 0082 18F0 brlo .L7
65:../avrlib/buffer.c **** {
66:../avrlib/buffer.c **** buffer->dataindex %= buffer->size;
184 .LM19:
185 0084 00D0 rcall __udivmodhi4
186 0086 8683 std Z+6,r24
187 0088 9783 std Z+7,r25
188 .L7:
67:../avrlib/buffer.c **** }
68:../avrlib/buffer.c **** buffer->datalength -= numbytes;
190 .LM20:
191 008a 2C1B sub r18,r28
192 008c 3D0B sbc r19,r29
193 008e 2483 std Z+4,r18
194 0090 3583 std Z+5,r19
195 0092 02C0 rjmp .L5
196 .L6:
69:../avrlib/buffer.c **** }
70:../avrlib/buffer.c **** else
71:../avrlib/buffer.c **** {
72:../avrlib/buffer.c **** // flush the whole buffer
73:../avrlib/buffer.c **** buffer->datalength = 0;
198 .LM21:
199 0094 1482 std Z+4,__zero_reg__
200 0096 1582 std Z+5,__zero_reg__
201 .L5:
202 /* epilogue: frame size=0 */
203 0098 DF91 pop r29
204 009a CF91 pop r28
205 009c 0895 ret
206 /* epilogue end (size=3) */
207 /* function bufferDumpFromFront size 33 (28) */
209 .Lscope2:
214 .global bufferGetAtIndex
216 bufferGetAtIndex:
74:../avrlib/buffer.c **** }
75:../avrlib/buffer.c **** }
76:../avrlib/buffer.c ****
77:../avrlib/buffer.c **** unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index)
78:../avrlib/buffer.c **** {
218 .LM22:
219 /* prologue: frame size=0 */
220 /* prologue end (size=0) */
221 009e FC01 movw r30,r24
79:../avrlib/buffer.c **** // return character at index in buffer
80:../avrlib/buffer.c **** return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)];
223 .LM23:
224 00a0 8681 ldd r24,Z+6
225 00a2 9781 ldd r25,Z+7
226 00a4 2281 ldd r18,Z+2
227 00a6 3381 ldd r19,Z+3
228 00a8 860F add r24,r22
229 00aa 971F adc r25,r23
230 00ac B901 movw r22,r18
231 00ae 00D0 rcall __udivmodhi4
232 00b0 0190 ld __tmp_reg__,Z+
233 00b2 F081 ld r31,Z
234 00b4 E02D mov r30,__tmp_reg__
235 00b6 E80F add r30,r24
236 00b8 F91F adc r31,r25
237 00ba 8081 ld r24,Z
81:../avrlib/buffer.c **** }
239 .LM24:
240 00bc 9927 clr r25
241 /* epilogue: frame size=0 */
242 00be 0895 ret
243 /* epilogue end (size=1) */
244 /* function bufferGetAtIndex size 17 (16) */
246 .Lscope3:
251 .global bufferAddToEnd
253 bufferAddToEnd:
82:../avrlib/buffer.c ****
83:../avrlib/buffer.c **** unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data)
84:../avrlib/buffer.c **** {
255 .LM25:
256 /* prologue: frame size=0 */
257 00c0 CF93 push r28
258 00c2 DF93 push r29
259 /* prologue end (size=2) */
260 00c4 EC01 movw r28,r24
261 00c6 462F mov r20,r22
85:../avrlib/buffer.c **** // make sure the buffer has room
86:../avrlib/buffer.c **** if(buffer->datalength < buffer->size)
263 .LM26:
264 00c8 2C81 ldd r18,Y+4
265 00ca 3D81 ldd r19,Y+5
266 00cc 6A81 ldd r22,Y+2
267 00ce 7B81 ldd r23,Y+3
268 00d0 2617 cp r18,r22
269 00d2 3707 cpc r19,r23
270 00d4 90F4 brsh .L11
87:../avrlib/buffer.c **** {
88:../avrlib/buffer.c **** // save data byte at end of buffer
89:../avrlib/buffer.c **** buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
272 .LM27:
273 00d6 8E81 ldd r24,Y+6
274 00d8 9F81 ldd r25,Y+7
275 00da 820F add r24,r18
276 00dc 931F adc r25,r19
277 00de 00D0 rcall __udivmodhi4
278 00e0 E881 ld r30,Y
279 00e2 F981 ldd r31,Y+1
280 00e4 E80F add r30,r24
281 00e6 F91F adc r31,r25
282 00e8 4083 st Z,r20
90:../avrlib/buffer.c **** // increment the length
91:../avrlib/buffer.c **** buffer->datalength++;
284 .LM28:
285 00ea 8C81 ldd r24,Y+4
286 00ec 9D81 ldd r25,Y+5
287 00ee 0196 adiw r24,1
288 00f0 8C83 std Y+4,r24
289 00f2 9D83 std Y+5,r25
92:../avrlib/buffer.c **** // return success
93:../avrlib/buffer.c **** return -1;
291 .LM29:
292 00f4 8FEF ldi r24,lo8(255)
293 00f6 90E0 ldi r25,hi8(255)
294 00f8 02C0 rjmp .L10
295 .L11:
94:../avrlib/buffer.c **** }
95:../avrlib/buffer.c **** else return 0;
297 .LM30:
298 00fa 80E0 ldi r24,lo8(0)
299 00fc 90E0 ldi r25,hi8(0)
300 .L10:
301 /* epilogue: frame size=0 */
302 00fe DF91 pop r29
303 0100 CF91 pop r28
304 0102 0895 ret
305 /* epilogue end (size=3) */
306 /* function bufferAddToEnd size 34 (29) */
308 .Lscope4:
312 .global bufferIsNotFull
314 bufferIsNotFull:
96:../avrlib/buffer.c **** }
97:../avrlib/buffer.c ****
98:../avrlib/buffer.c **** unsigned char bufferIsNotFull(cBuffer* buffer)
99:../avrlib/buffer.c **** {
316 .LM31:
317 /* prologue: frame size=0 */
318 /* prologue end (size=0) */
319 0104 FC01 movw r30,r24
100:../avrlib/buffer.c **** // check to see if the buffer has room
101:../avrlib/buffer.c **** // return true if there is room
102:../avrlib/buffer.c **** return (buffer->datalength < buffer->size);
321 .LM32:
322 0106 40E0 ldi r20,lo8(0)
323 0108 50E0 ldi r21,hi8(0)
324 010a 2481 ldd r18,Z+4
325 010c 3581 ldd r19,Z+5
326 010e 8281 ldd r24,Z+2
327 0110 9381 ldd r25,Z+3
328 0112 2817 cp r18,r24
329 0114 3907 cpc r19,r25
330 0116 10F4 brsh .L14
332 .LM33:
333 0118 41E0 ldi r20,lo8(1)
334 011a 50E0 ldi r21,hi8(1)
335 .L14:
103:../avrlib/buffer.c **** }
337 .LM34:
338 011c CA01 movw r24,r20
339 /* epilogue: frame size=0 */
340 011e 0895 ret
341 /* epilogue end (size=1) */
342 /* function bufferIsNotFull size 14 (13) */
344 .Lscope5:
348 .global bufferFlush
350 bufferFlush:
104:../avrlib/buffer.c ****
105:../avrlib/buffer.c **** void bufferFlush(cBuffer* buffer)
106:../avrlib/buffer.c **** {
352 .LM35:
353 /* prologue: frame size=0 */
354 /* prologue end (size=0) */
107:../avrlib/buffer.c **** // flush contents of the buffer
108:../avrlib/buffer.c **** buffer->datalength = 0;
356 .LM36:
357 0120 FC01 movw r30,r24
358 0122 1482 std Z+4,__zero_reg__
359 0124 1582 std Z+5,__zero_reg__
360 /* epilogue: frame size=0 */
361 0126 0895 ret
362 /* epilogue end (size=1) */
363 /* function bufferFlush size 4 (3) */
365 .Lscope6:
367 .text
369 Letext:
370 /* File "../avrlib/buffer.c": code 148 = 0x0094 ( 129), prologues 6, epilogues 13 */
DEFINED SYMBOLS
*ABS*:00000000 buffer.c
*ABS*:0000003f __SREG__
*ABS*:0000003e __SP_H__
*ABS*:0000003d __SP_L__
*ABS*:00000000 __tmp_reg__
*ABS*:00000001 __zero_reg__
/var/tmp//ccWNR2QI.s:46 .text:00000000 bufferInit
/var/tmp//ccWNR2QI.s:79 .text:00000014 bufferGetFromFront
/var/tmp//ccWNR2QI.s:152 .text:0000005c bufferDumpFromFront
/var/tmp//ccWNR2QI.s:216 .text:0000009e bufferGetAtIndex
/var/tmp//ccWNR2QI.s:253 .text:000000c0 bufferAddToEnd
/var/tmp//ccWNR2QI.s:314 .text:00000104 bufferIsNotFull
/var/tmp//ccWNR2QI.s:350 .text:00000120 bufferFlush
/var/tmp//ccWNR2QI.s:369 .text:00000128 Letext
UNDEFINED SYMBOLS
__do_copy_data
__do_clear_bss
__udivmodhi4

View File

@ -1,425 +0,0 @@
/*
Copyright (c) 1996. The Regents of the University of California (Regents).
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for educational, research, and not-for-profit purposes, without
fee and without a signed licensing agreement, is hereby granted, provided that
the above copyright notice, this paragraph and the following two paragraphs
appear in all copies, modifications, and distributions. Contact The Office of
Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
Author: Matt Wright
Version 2.2: Calls htonl in the right places 20000620
Version 2.3: Gets typed messages right.
*/
/* Here are the possible values of the state field: */
#define EMPTY 0 /* Nothing written to packet yet */
#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */
#define NEED_COUNT 2 /* Just opened a bundle; must write message name or
open another bundle */
#define GET_ARGS 3 /* Getting arguments to a message. If we see a message
name or a bundle open/close then the current message
will end. */
#define DONE 4 /* All open bundles have been closed, so can't write
anything else */
#include "OSC-client.h"
// defines to make this work with the atmel
//
#include "progmem.h"
#include "debug.h"
//#define printf debug
//
char *OSC_errorMessage;
static int OSC_padString(char *dest, char PROGMEM *str);
static int OSC_WritePadding(char *dest, int i);
static int CheckTypeTag(OSCbuf *buf, char expectedType);
void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) {
buf->buffer = byteArray;
buf->size = size;
OSC_resetBuffer(buf);
}
void OSC_resetBuffer(OSCbuf *buf) {
buf->bufptr = buf->buffer;
buf->state = EMPTY;
buf->bundleDepth = 0;
buf->prevCounts[0] = 0;
buf->gettingFirstUntypedArg = 0;
buf->typeStringPtr = 0;
}
int OSC_isBufferEmpty(OSCbuf *buf) {
return buf->bufptr == buf->buffer;
}
int OSC_freeSpaceInBuffer(OSCbuf *buf) {
return buf->size - (buf->bufptr - buf->buffer);
}
int OSC_isBufferDone(OSCbuf *buf) {
return (buf->state == DONE || buf->state == ONE_MSG_ARGS);
}
char *OSC_getPacket(OSCbuf *buf) {
#ifdef ERROR_CHECK_GETPACKET
if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
return buf->buffer;
} else {
OSC_errorMessage = "Packet has unterminated bundles";
return 0;
}
#else
return buf->buffer;
#endif
}
int OSC_packetSize(OSCbuf *buf) {
#ifdef ERROR_CHECK_PACKETSIZE
if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
return (buf->bufptr - buf->buffer);
} else {
OSC_errorMessage = "Packet has unterminated bundles";
return 0;
}
#else
return (buf->bufptr - buf->buffer);
#endif
}
#define CheckOverflow(buf, bytesNeeded) { \
if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) { \
OSC_errorMessage = "buffer overflow"; \
return 1; \
} \
}
static void PatchMessageSize(OSCbuf *buf) {
int4byte size;
size = buf->bufptr - ((char *) buf->thisMsgSize) - 4;
*(buf->thisMsgSize) = htonl(size);
}
int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) {
if (buf->state == ONE_MSG_ARGS) {
OSC_errorMessage = "Can't open a bundle in a one-message packet";
return 3;
}
if (buf->state == DONE) {
OSC_errorMessage = "This packet is finished; can't open a new bundle";
return 4;
}
if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) {
OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h";
return 2;
}
if (CheckTypeTag(buf, '\0')) return 9;
if (buf->state == GET_ARGS) {
PatchMessageSize(buf);
}
if (buf->state == EMPTY) {
/* Need 16 bytes for "#bundle" and time tag */
CheckOverflow(buf, 16);
} else {
/* This bundle is inside another bundle, so we need to leave
a blank size count for the size of this current bundle. */
CheckOverflow(buf, 20);
*((int4byte *)buf->bufptr) = 0xaaaaaaaa;
buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr;
buf->bufptr += 4;
}
buf->bufptr += OSC_padString(buf->bufptr, "#bundle");
*((OSCTimeTag *) buf->bufptr) = tt;
if (htonl(1L) != 1L) {
/* Byte swap the 8-byte integer time tag */
int4byte *intp = (int4byte *)buf->bufptr;
intp[0] = htonl(intp[0]);
intp[1] = htonl(intp[1]);
#ifdef HAS8BYTEINT
{ /* tt is a 64-bit int so we have to swap the two 32-bit words.
(Otherwise tt is a struct of two 32-bit words, and even though
each word was wrong-endian, they were in the right order
in the struct.) */
int4byte temp = intp[0];
intp[0] = intp[1];
intp[1] = temp;
}
#endif
}
buf->bufptr += sizeof(OSCTimeTag);
buf->state = NEED_COUNT;
buf->gettingFirstUntypedArg = 0;
buf->typeStringPtr = 0;
return 0;
}
int OSC_closeBundle(OSCbuf *buf) {
if (buf->bundleDepth == 0) {
/* This handles EMPTY, ONE_MSG, ARGS, and DONE */
OSC_errorMessage = "Can't close bundle; no bundle is open!";
return 5;
}
if (CheckTypeTag(buf, '\0')) return 9;
if (buf->state == GET_ARGS) {
PatchMessageSize(buf);
}
if (buf->bundleDepth == 1) {
/* Closing the last bundle: No bundle size to patch */
buf->state = DONE;
} else {
/* Closing a sub-bundle: patch bundle size */
int4byte size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4;
*(buf->prevCounts[buf->bundleDepth]) = htonl(size);
buf->state = NEED_COUNT;
}
--buf->bundleDepth;
buf->gettingFirstUntypedArg = 0;
buf->typeStringPtr = 0;
return 0;
}
int OSC_closeAllBundles(OSCbuf *buf) {
if (buf->bundleDepth == 0) {
/* This handles EMPTY, ONE_MSG, ARGS, and DONE */
OSC_errorMessage = "Can't close all bundles; no bundle is open!";
return 6;
}
if (CheckTypeTag(buf, '\0')) return 9;
while (buf->bundleDepth > 0) {
OSC_closeBundle(buf);
}
buf->typeStringPtr = 0;
return 0;
}
int OSC_writeAddress(OSCbuf *buf, char PROGMEM *name) {
int4byte paddedLength;
if (buf->state == ONE_MSG_ARGS) {
//debug(PSTR("This packet is not a bundle, so you can't write another address"));
return 7;
}
if (buf->state == DONE) {
//debug(PSTR("This packet is finished; can't write another address"));
return 8;
}
if (CheckTypeTag(buf, '\0')) return 9;
paddedLength = OSC_effectiveStringLength(name);
if (buf->state == EMPTY) {
/* This will be a one-message packet, so no sizes to worry about */
CheckOverflow(buf, paddedLength);
buf->state = ONE_MSG_ARGS;
} else {
/* GET_ARGS or NEED_COUNT */
CheckOverflow(buf, 4+paddedLength);
if (buf->state == GET_ARGS) {
/* Close the old message */
PatchMessageSize(buf);
}
buf->thisMsgSize = (int4byte *)buf->bufptr;
*(buf->thisMsgSize) = 0xbbbbbbbb;
buf->bufptr += 4;
buf->state = GET_ARGS;
}
/* Now write the name */
buf->bufptr += OSC_padString(buf->bufptr, name);
buf->typeStringPtr = 0;
buf->gettingFirstUntypedArg = 1;
return 0;
}
int OSC_writeAddressAndTypes(OSCbuf *buf, char PROGMEM *name, char PROGMEM *types) {
int result;
int4byte paddedLength;
if (CheckTypeTag(buf, '\0')) return 9;
result = OSC_writeAddress(buf, name);
if (result) return result;
paddedLength = OSC_effectiveStringLength(types);
CheckOverflow(buf, paddedLength);
buf->typeStringPtr = buf->bufptr + 1; /* skip comma */
buf->bufptr += OSC_padString(buf->bufptr, types);
buf->gettingFirstUntypedArg = 0;
return 0;
}
static int CheckTypeTag(OSCbuf *buf, char expectedType) {
if (buf->typeStringPtr) {
if (*(buf->typeStringPtr) != expectedType) {
if (expectedType == '\0') {
OSC_errorMessage =
"According to the type tag I expected more arguments.";
} else if (*(buf->typeStringPtr) == '\0') {
OSC_errorMessage =
"According to the type tag I didn't expect any more arguments.";
} else {
OSC_errorMessage =
"According to the type tag I expected an argument of a different type.";
// printf("* Expected %c, string now %s\n", expectedType, buf->typeStringPtr);
}
return 9;
}
++(buf->typeStringPtr);
}
return 0;
}
int OSC_writeFloatArg(OSCbuf *buf, float arg) {
int4byte *intp;
CheckOverflow(buf, 4);
if (CheckTypeTag(buf, 'f')) return 9;
/* Pretend arg is a long int so we can use htonl() */
intp = ((int4byte *) &arg);
*((int4byte *) buf->bufptr) = htonl(*intp);
buf->bufptr += 4;
buf->gettingFirstUntypedArg = 0;
return 0;
}
int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) {
int i;
int4byte *intp;
CheckOverflow(buf, 4 * numFloats);
/* Pretend args are long ints so we can use htonl() */
intp = ((int4byte *) args);
for (i = 0; i < numFloats; i++) {
if (CheckTypeTag(buf, 'f')) return 9;
*((int4byte *) buf->bufptr) = htonl(intp[i]);
buf->bufptr += 4;
}
buf->gettingFirstUntypedArg = 0;
return 0;
}
int OSC_writeIntArg(OSCbuf *buf, int4byte arg) {
CheckOverflow(buf, 4);
if (CheckTypeTag(buf, 'i')) return 9;
*((int4byte *) buf->bufptr) = htonl(arg);
buf->bufptr += 4;
buf->gettingFirstUntypedArg = 0;
return 0;
}
int OSC_writeStringArg(OSCbuf *buf, char PROGMEM *arg) {
int len;
if (CheckTypeTag(buf, 's')) return 9;
len = OSC_effectiveStringLength(arg);
CheckOverflow(buf, len);
buf->bufptr += OSC_padString(buf->bufptr, arg);
buf->gettingFirstUntypedArg = 0;
return 0;
}
#define STRING_ALIGN_PAD 4
int OSC_effectiveStringLength(char PROGMEM *string) {
int len = strlen_P(string) + 1; /* We need space for the null char. */
/* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */
if ((len % STRING_ALIGN_PAD) != 0) {
len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD);
}
return len;
}
static int OSC_padString(char *dest, char PROGMEM *str) {
int i;
char c;
for (i = 0; (c = pgm_read_byte(str+i)) != '\0'; i++) {
dest[i] = c;
}
return OSC_WritePadding(dest, i);
}
static int OSC_WritePadding(char *dest, int i) {
dest[i] = '\0';
i++;
for (; (i % STRING_ALIGN_PAD) != 0; i++) {
dest[i] = '\0';
}
return i;
}

View File

@ -1,192 +0,0 @@
/*
Copyright (c) 1996,1997. The Regents of the University of California (Regents).
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for educational, research, and not-for-profit purposes, without
fee and without a signed licensing agreement, is hereby granted, provided that
the above copyright notice, this paragraph and the following two paragraphs
appear in all copies, modifications, and distributions. Contact The Office of
Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
OSC-client.h: library for constructing OpenSoundControl messages.
Derived from SynthControl.h
Author: Matt Wright
Version 0.1: 6/13/97
Version 0.2: 7/21/2000: Support for type-tagged messages
General notes:
This library abstracts away the data format for the OpenSoundControl
protocol. Users of this library can construct OpenSoundControl packets
with a function call interface instead of knowing how to lay out the bits.
All issues of memory allocation are deferred to the user of this library.
There are two data structures that the user must allocate. The first
is the actual buffer that the message will be written into. This buffer
can be any size, but if it's too small there's a possibility that it
will become overfull. The other data structure is called an OSCbuf,
and it holds all the state used by the library as it's constructing
a buffer.
All procedures that have the possibility of an error condition return int,
with 0 indicating no error and nonzero indicating an error. The variable
OSC_errorMessage will be set to point to a string containing an error
message explaining what the problem is.
*/
#include "OSC-timetag.h"
#include "global.h"
#include <progmem.h>
#define ATMEL
#ifdef ATMEL
#define htonl(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#endif
/* The int4byte type has to be a 4-byte integer. You may have to
change this to long or something else on your system. */
#ifdef __MWERKS__
/* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is
always 4 bytes */
typedef long int4byte;
#else
typedef s32 int4byte;
#endif
/* The maximum depth of bundles within bundles within bundles within...
This is the size of a static array. If you exceed this limit you'll
get an error message. */
#define MAX_BUNDLE_NESTING 32
/* Don't ever manipulate the data in the OSCbuf struct directly. (It's
declared here in the header file only so your program will be able to
declare variables of type OSCbuf and have the right amount of memory
be allocated.) */
typedef struct OSCbuf_struct {
char *buffer; /* The buffer to hold the OSC packet */
int size; /* Size of the buffer */
char *bufptr; /* Current position as we fill the buffer */
int state; /* State of partially-constructed message */
int4byte *thisMsgSize; /* Pointer to count field before
currently-being-written message */
int4byte *prevCounts[MAX_BUNDLE_NESTING];
/* Pointers to count field before each currently
open bundle */
int bundleDepth; /* How many sub-sub-bundles are we in now? */
char *typeStringPtr; /* This pointer advances through the type
tag string as you add arguments. */
int gettingFirstUntypedArg; /* nonzero if this message doesn't have
a type tag and we're waiting for the 1st arg */
} OSCbuf;
/* Initialize the given OSCbuf. The user of this module must pass in the
block of memory that this OSCbuf will use for a buffer, and the number of
bytes in that block. (It's the user's job to allocate the memory because
you do it differently in different systems.) */
void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray);
/* Reset the given OSCbuf. Do this after you send out the contents of
the buffer and want to start writing new data into it. */
void OSC_resetBuffer(OSCbuf *buf);
/* Is the buffer empty? (I.e., would it be stupid to send the buffer
contents to the synth?) */
int OSC_isBufferEmpty(OSCbuf *buf);
/* How much space is left in the buffer? */
int OSC_freeSpaceInBuffer(OSCbuf *buf);
/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */
int OSC_isBufferDone(OSCbuf *buf);
/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone()
returns true), call these two procedures to get the OSC packet that's been
assembled and its size in bytes. (And then call OSC_resetBuffer() if you
want to re-use this OSCbuf for the next packet.) */
char *OSC_getPacket(OSCbuf *buf);
int OSC_packetSize(OSCbuf *buf);
/* Here's the basic model for building up OSC messages in an OSCbuf:
- Make sure the OSCbuf has been initialized with OSC_initBuffer().
- To open a bundle, call OSC_openBundle(). You can then write
messages or open new bundles within the bundle you opened.
Call OSC_closeBundle() to close the bundle. Note that a packet
does not have to have a bundle; it can instead consist of just a
single message.
- For each message you want to send:
- Call OSC_writeAddress() with the name of your message. (In
addition to writing your message name into the buffer, this
procedure will also leave space for the size count of this message.)
- Alternately, call OSC_writeAddressAndTypes() with the name of
your message and with a type string listing the types of all the
arguments you will be putting in this message.
- Now write each of the arguments into the buffer, by calling one of:
OSC_writeFloatArg()
OSC_writeFloatArgs()
OSC_writeIntArg()
OSC_writeStringArg()
- Now your message is complete; you can send out the buffer or you can
add another message to it.
*/
int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt);
int OSC_closeBundle(OSCbuf *buf);
int OSC_closeAllBundles(OSCbuf *buf);
int OSC_writeAddress(OSCbuf *buf, char PROGMEM *name);
int OSC_writeAddressAndTypes(OSCbuf *buf, char PROGMEM *name, char PROGMEM *types);
int OSC_writeFloatArg(OSCbuf *buf, float arg);
int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args);
int OSC_writeIntArg(OSCbuf *buf, int4byte arg);
int OSC_writeStringArg(OSCbuf *buf, char PROGMEM *arg);
extern char *OSC_errorMessage;
/* How many bytes will be needed in the OSC format to hold the given
string? The length of the string, plus the null char, plus any padding
needed for 4-byte alignment. */
int OSC_effectiveStringLength(char PROGMEM *string);

View File

@ -1,175 +0,0 @@
/*
Copyright (c) 1998. The Regents of the University of California (Regents).
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for educational, research, and not-for-profit purposes, without
fee and without a signed licensing agreement, is hereby granted, provided that
the above copyright notice, this paragraph and the following two paragraphs
appear in all copies, modifications, and distributions. Contact The Office of
Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
The OpenSound Control WWW page is
http://www.cnmat.berkeley.edu/OpenSoundControl
*/
/*
OSC_timeTag.c: library for manipulating OSC time tags
Matt Wright, 5/29/97
Version 0.2 (9/11/98): cleaned up so no explicit type names in the .c file.
*/
#include "OSC-timetag.h"
#ifdef HAS8BYTEINT
#define TWO_TO_THE_32_FLOAT 4294967296.0f
OSCTimeTag OSCTT_Immediately(void) {
return (OSCTimeTag) 1;
}
OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) {
return (OSCTimeTag) 0xffffffffffffffff;
}
OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) {
int64 offset = (int64) (secondsOffset * TWO_TO_THE_32_FLOAT);
/* printf("* OSCTT_PlusSeconds %llx plus %f seconds (i.e., %lld offset) is %llx\n", original,
secondsOffset, offset, original + offset); */
return original + offset;
}
int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) {
#if 0
printf("***** OSCTT_Compare(%llx, %llx): %d\n", left, right,
(left<right) ? -1 : ((left == right) ? 0 : 1));
#endif
if (left < right) {
return -1;
} else if (left == right) {
return 0;
} else {
return 1;
}
}
#ifdef __sgi
#include <sys/time.h>
#define SECONDS_FROM_1900_to_1970 2208988800 /* 17 leap years */
#define TWO_TO_THE_32_OVER_ONE_MILLION 4295
OSCTimeTag OSCTT_CurrentTime(void) {
uint64 result;
uint32 usecOffset;
struct timeval tv;
struct timezone tz;
BSDgettimeofday(&tv, &tz);
/* First get the seconds right */
result = (unsigned) SECONDS_FROM_1900_to_1970 +
(unsigned) tv.tv_sec -
(unsigned) 60 * tz.tz_minuteswest +
(unsigned) (tz.tz_dsttime ? 3600 : 0);
#if 0
/* No timezone, no DST version ... */
result = (unsigned) SECONDS_FROM_1900_to_1970 +
(unsigned) tv.tv_sec;
#endif
/* make seconds the high-order 32 bits */
result = result << 32;
/* Now get the fractional part. */
usecOffset = (unsigned) tv.tv_usec * (unsigned) TWO_TO_THE_32_OVER_ONE_MILLION;
/* printf("** %ld microsec is offset %x\n", tv.tv_usec, usecOffset); */
result += usecOffset;
/* printf("* OSCTT_CurrentTime is %llx\n", result); */
return result;
}
#else /* __sgi */
/* Instead of asking your operating system what time it is, it might be
clever to find out the current time at the instant your application
starts audio processing, and then keep track of the number of samples
output to know how much time has passed. */
/* Loser version for systems that have no ability to tell the current time: */
OSCTimeTag OSCTT_CurrentTime(void) {
return (OSCTimeTag) 1;
}
#endif /* __sgi */
#else /* Not HAS8BYTEINT */
OSCTimeTag OSCTT_CurrentTime(void) {
OSCTimeTag result;
result.seconds = 0;
result.fraction = 1;
return result;
}
OSCTimeTag OSCTT_BiggestPossibleTimeTag(void) {
OSCTimeTag result;
result.seconds = 0xffffffff;
result.fraction = 0xffffffff;
return result;
}
OSCTimeTag OSCTT_Immediately(void) {
OSCTimeTag result;
result.seconds = 0;
result.fraction = 1;
return result;
}
OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) {
OSCTimeTag result;
result.seconds = 0;
result.fraction = 1;
return result;
}
int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right) {
/* Untested! */
int highResult = left.seconds - right.seconds;
if (highResult != 0) return highResult;
return left.fraction - right.fraction;
}
#endif /* HAS8BYTEINT */

View File

@ -1,95 +0,0 @@
/*
Copyright (c) 1998. The Regents of the University of California (Regents).
All Rights Reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for educational, research, and not-for-profit purposes, without
fee and without a signed licensing agreement, is hereby granted, provided that
the above copyright notice, this paragraph and the following two paragraphs
appear in all copies, modifications, and distributions. Contact The Office of
Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley,
CA 94720-1620, (510) 643-7201, for commercial licensing opportunities.
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING
DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
The OpenSound Control WWW page is
http://www.cnmat.berkeley.edu/OpenSoundControl
*/
/*
OSC_timeTag.h: library for manipulating OSC time tags
Matt Wright, 5/29/97
Time tags in OSC have the same format as in NTP: 64 bit fixed point, with the
top 32 bits giving number of seconds sinve midnight 1/1/1900 and the bottom
32 bits giving fractional parts of a second. We represent this by a 64-bit
unsigned long if possible, or else a struct.
NB: On many architectures with 64-bit ints, it's illegal (like maybe a bus error)
to dereference a pointer to a 64-bit int that's not 64-bit aligned.
*/
#ifndef OSC_TIMETAG
#define OSC_TIMETAG
#include <inttypes.h>
#ifdef __sgi
#define HAS8BYTEINT
/* You may have to change this typedef if there's some other
way to specify 64 bit ints on your system */
typedef long long int64;
typedef unsigned long long uint64;
typedef unsigned long uint32;
#else
/* You may have to redefine this typedef if ints on your system
aren't 32 bits. */
typedef uint32_t uint32;
#endif
#ifdef HAS8BYTEINT
typedef uint64 OSCTimeTag;
#else
typedef struct {
uint32 seconds;
uint32 fraction;
} OSCTimeTag;
#endif
/* Return a time tag representing the current time (as of when this
procedure is called). */
OSCTimeTag OSCTT_CurrentTime(void);
/* Return the time tag 0x0000000000000001, indicating to the receiving device
that it should process the message immediately. */
OSCTimeTag OSCTT_Immediately(void);
/* Return the time tag 0xffffffffffffffff, a time so far in the future that
it's effectively infinity. */
OSCTimeTag OSCTT_BiggestPossibleTimeTag(void);
/* Given a time tag and a number of seconds to add to the time tag, return
the new time tag */
OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset);
/* Compare two time tags. Return negative if first is < second, 0 if
they're equal, and positive if first > second. */
int OSCTT_Compare(OSCTimeTag left, OSCTimeTag right);
#endif /* OSC_TIMETAG */

View File

@ -1,55 +0,0 @@
#include <io.h>
#include <stdarg.h>
#include "debug.h"
#include "lcd.h"
#include "rprintf.h"
#include "timer.h"
#include "osc.h"
u08 debugMode = 0;
u08 lcdDebugX;
u08 lcdDebugY;
void debugInitLCD(u08 x, u08 y) {
lcdInit();
lcdClear();
lcdDebugX = x;
lcdDebugY = y;
debugMode |= DEBUG_MODE_LCD;
debug(PSTR("LCD Debug init()"));
}
void debugInitOSC(void) {
oscInit();
debugMode |= DEBUG_MODE_OSC;
}
void debug(const char PROGMEM *fmt) {
int code;
if (debugMode & DEBUG_MODE_OSC) {
oscSendMessageString("/debug",fmt);
}
if (debugMode & DEBUG_MODE_LCD) {
rprintfInit(&lcdDataWrite);
lcdGotoXY(lcdDebugX,lcdDebugY);
rprintf1RamRom(STRING_IN_ROM, fmt);
}
}
// debugFlush assumes that timerInit() have been called already
void debugFlash(const u08 port, const u08 pin) {
sbi(DDR(port), pin);
cbi(port, pin);
timerPause(500);
sbi(port, pin);
}

View File

@ -1,22 +0,0 @@
#ifndef _DEBUG_H
#define _DEBUG_H
#include <progmem.h>
#include "global.h"
#define DEBUG_MODE_LCD 0x01
#define DEBUG_MODE_SERIAL 0x02
#define DEBUG_MODE_OSC 0x04
void debugInitLCD(u08 x, u08 y);
void debugInitOSC(void);
void debug(const char * fmt);
void debugFlash(u08 port, u08 pin);
#endif

View File

@ -1,48 +0,0 @@
// Midi.c
//
// Midi output routines for the atmel atmega163 (and others)
//
// depends on avrlib for buffer
//
#include "uart.h"
#include "midi.h"
#include "debug.h"
void midiInit() {
uartInit();
uartSetBaudRate(MIDI_BAUD_RATE);
}
u08 midiNoteOnOut(u08 note, u08 vel, u08 channel) {
uartSendByte(MIDI_NOTE_ON | (channel & MIDI_CHANNEL_MASK));
uartSendByte(MIDI_DATA_MASK & note);
uartSendByte(MIDI_DATA_MASK & vel);
return 0;
}
u08 midiNoteOffOut(u08 note, u08 vel, u08 channel) {
uartSendByte(MIDI_NOTE_OFF | (channel & MIDI_CHANNEL_MASK));
uartSendByte(MIDI_DATA_MASK & note);
uartSendByte(MIDI_DATA_MASK & vel);
return 0;
}
u08 midiControlChangeOut(u08 controller, u08 value, u08 channel) {
uartSendByte(MIDI_CONTROL_CHANGE | (channel & MIDI_CHANNEL_MASK));
uartSendByte(MIDI_DATA_MASK & controller);
uartSendByte(MIDI_DATA_MASK & value);
return 0;
}
u08 midiProgramChangeOut(u08 program, u08 channel) {
uartSendByte(MIDI_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_MASK));
uartSendByte(MIDI_DATA_MASK & program);
return 0;
}

View File

@ -1,30 +0,0 @@
#ifndef _MIDI_H
#define _MIDI_H
#define MIDI_NOTE_ON 0x90
#define MIDI_NOTE_OFF 0x80
// 1001cccc 0nnnnnnn 0vvvvvvv
#define MIDI_POLY_PRESSURE 0xA0
// 1011cccc 0nnnnnnn 0vvvvvvv
#define MIDI_CONTROL_CHANGE 0xB0
// 1100cccc 0ppppppp
#define MIDI_PROGRAM_CHANGE 0xC0
#define MIDI_DATA_MASK 0x7F
#define MIDI_STATUS_MASK 0xF0
#define MIDI_CHANNEL_MASK 0x0F
#define MIDI_BAUD_RATE 31250
#include "global.h"
#include "buffer.h"
void midiInit(void);
u08 midiNoteOnOut(u08 note, u08 vel, u08 channel);
u08 midiNoteOffOut(u08 note, u08 vel, u08 channel);
u08 midiControlChangeOut(u08 controller, u08 value, u08 channel);
u08 midiProgramChangeOut(u08 program, u08 channel);
#endif

View File

@ -1,96 +0,0 @@
// osc.c
//
// Open Sound Control message sending fn's for avrmini
//
// Scott Wilson
// July 21, 2002
//
#include <progmem.h>
#include <stdarg.h>
#include "OSC-client.h"
#include "osc.h"
//#include "debug.h"
#include "uart.h"
#define OSC_BUFFER_LEN 40
void _oscSendPacket();
u08 oscDataBuffer[OSC_BUFFER_LEN];
OSCbuf oscbuf;
void oscInit() {
uartInit();
OSC_initBuffer(&oscbuf, OSC_BUFFER_LEN, oscDataBuffer);
// debug(PSTR("OSC init ok packet"));
}
// call oscInit() and uartInit() before using this function
void oscSendMessage(const char PROGMEM *address) {
OSC_writeAddress(&oscbuf, address);
_oscSendPacket();
}
void oscSendMessageInt(const char PROGMEM *address, s32 arg) {
OSC_writeAddress(&oscbuf, address);
OSC_writeIntArg(&oscbuf, arg);
_oscSendPacket();
}
void oscSendMessageIntInt(const char PROGMEM *address, s32 arg, s32 arg2) {
OSC_writeAddress(&oscbuf, address);
OSC_writeIntArg(&oscbuf, arg);
OSC_writeIntArg(&oscbuf, arg2);
_oscSendPacket();
}
void oscSendMessageString(const char PROGMEM *address, const char PROGMEM *arg) {
OSC_writeAddress(&oscbuf, address);
OSC_writeStringArg(&oscbuf, arg);
_oscSendPacket();
}
void _oscSendPacket() {
u08 j;
u08 *oscDataPtr;
u08 oscPacketSize;
register u08 checksum=0;
register u08 data;
// send the packet
if (OSC_isBufferDone(&oscbuf)) {
// begin packet sync byte
uartSendByte((u08)0xbe);
// send length byte
uartSendByte((u08)(OSC_BUFFER_LEN - OSC_freeSpaceInBuffer(&oscbuf)));
oscDataPtr = OSC_getPacket(&oscbuf);
oscPacketSize = OSC_packetSize(&oscbuf);
// debug(PSTR("packet size: %x"),(unsigned int)oscPacketSize);
for (j=0; j<oscPacketSize; j++) {
data = *(oscDataPtr+j);
checksum += data;
uartSendByte(data);
}
// send checksum byte
uartSendByte(checksum);
OSC_resetBuffer(&oscbuf);
} else {
//debug(PSTR("Error creating OSC packet"));
}
}

View File

@ -1,24 +0,0 @@
// osc.h
//
// Open Sound Control message sending fn's for avrmini
//
// Scott Wilson
// July 21, 2002
//
#ifndef _OSC_H
#define _OSC_H
#include "global.h"
#include <progmem.h>
#define oscSendMessageOneArg oscSendMessageInt
void oscInit(void);
void oscSendMessage(const char PROGMEM *address);
void oscSendMessageInt(const char PROGMEM *address, s32 arg);
void oscSendMessageIntInt(const char PROGMEM *address, s32 arg, s32 arg2);
void oscSendMessageString(const char PROGMEM *address, const char PROGMEM *arg);
#endif

View File

@ -1,448 +0,0 @@
/*! \file cmdline.c \brief Command-Line Interface Library. */
//*****************************************************************************
//
// File Name : 'cmdline.c'
// Title : Command-Line Interface Library
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.07.16
// Revised : 2003.07.23
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
//----- Include Files ---------------------------------------------------------
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
#include <avr/signal.h> // include "signal" names (interrupt names)
#include <avr/interrupt.h> // include interrupt support
#include <avr/pgmspace.h> // include AVR program memory support
#include <string.h> // include standard C string functions
#include <stdlib.h> // include stdlib for string conversion functions
#include "global.h" // include our global settings
#include "cmdline.h"
// include project-specific configuration
#include "cmdlineconf.h"
// defines
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
#define ASCII_CR 0x0D
#define ASCII_LF 0x0A
#define ASCII_ESC 0x1B
#define ASCII_DEL 0x7F
#define VT100_ARROWUP 'A'
#define VT100_ARROWDOWN 'B'
#define VT100_ARROWRIGHT 'C'
#define VT100_ARROWLEFT 'D'
#define CMDLINE_HISTORY_SAVE 0
#define CMDLINE_HISTORY_PREV 1
#define CMDLINE_HISTORY_NEXT 2
// Global variables
// strings
u08 PROGMEM CmdlinePrompt[] = "cmd>";
u08 PROGMEM CmdlineNotice[] = "cmdline: ";
u08 PROGMEM CmdlineCmdNotFound[] = "command not found";
// command list
// -commands are null-terminated strings
static char CmdlineCommandList[CMDLINE_MAX_COMMANDS][CMDLINE_MAX_CMD_LENGTH];
// command function pointer list
static CmdlineFuncPtrType CmdlineFunctionList[CMDLINE_MAX_COMMANDS];
// number of commands currently registered
u08 CmdlineNumCommands;
u08 CmdlineBuffer[CMDLINE_BUFFERSIZE];
u08 CmdlineBufferLength;
u08 CmdlineBufferEditPos;
u08 CmdlineInputVT100State;
u08 CmdlineHistory[CMDLINE_HISTORYSIZE][CMDLINE_BUFFERSIZE];
CmdlineFuncPtrType CmdlineExecFunction;
// Functions
// function pointer to single character output routine
static void (*cmdlineOutputFunc)(unsigned char c);
void cmdlineInit(void)
{
// reset vt100 processing state
CmdlineInputVT100State = 0;
// initialize input buffer
CmdlineBufferLength = 0;
CmdlineBufferEditPos = 0;
// initialize executing function
CmdlineExecFunction = 0;
// initialize command list
CmdlineNumCommands = 0;
}
void cmdlineAddCommand(u08* newCmdString, CmdlineFuncPtrType newCmdFuncPtr)
{
// add command string to end of command list
strcpy(CmdlineCommandList[CmdlineNumCommands], newCmdString);
// add command function ptr to end of function list
CmdlineFunctionList[CmdlineNumCommands] = newCmdFuncPtr;
// increment number of registered commands
CmdlineNumCommands++;
}
void cmdlineSetOutputFunc(void (*output_func)(unsigned char c))
{
// set new output function
cmdlineOutputFunc = output_func;
// should we really do this?
// print a prompt
//cmdlinePrintPrompt();
}
void cmdlineInputFunc(unsigned char c)
{
u08 i;
// process the received character
// VT100 handling
// are we processing a VT100 command?
if(CmdlineInputVT100State == 2)
{
// we have already received ESC and [
// now process the vt100 code
switch(c)
{
case VT100_ARROWUP:
cmdlineDoHistory(CMDLINE_HISTORY_PREV);
break;
case VT100_ARROWDOWN:
cmdlineDoHistory(CMDLINE_HISTORY_NEXT);
break;
case VT100_ARROWRIGHT:
// if the edit position less than current string length
if(CmdlineBufferEditPos < CmdlineBufferLength)
{
// increment the edit position
CmdlineBufferEditPos++;
// move cursor forward one space (no erase)
cmdlineOutputFunc(ASCII_ESC);
cmdlineOutputFunc('[');
cmdlineOutputFunc(VT100_ARROWRIGHT);
}
else
{
// else, ring the bell
cmdlineOutputFunc(ASCII_BEL);
}
break;
case VT100_ARROWLEFT:
// if the edit position is non-zero
if(CmdlineBufferEditPos)
{
// decrement the edit position
CmdlineBufferEditPos--;
// move cursor back one space (no erase)
cmdlineOutputFunc(ASCII_BS);
}
else
{
// else, ring the bell
cmdlineOutputFunc(ASCII_BEL);
}
break;
default:
break;
}
// done, reset state
CmdlineInputVT100State = 0;
return;
}
else if(CmdlineInputVT100State == 1)
{
// we last received [ESC]
if(c == '[')
{
CmdlineInputVT100State = 2;
return;
}
else
CmdlineInputVT100State = 0;
}
else
{
// anything else, reset state
CmdlineInputVT100State = 0;
}
// Regular handling
if( (c >= 0x20) && (c < 0x7F) )
{
// character is printable
// is this a simple append
if(CmdlineBufferEditPos == CmdlineBufferLength)
{
// echo character to the output
cmdlineOutputFunc(c);
// add it to the command line buffer
CmdlineBuffer[CmdlineBufferEditPos++] = c;
// update buffer length
CmdlineBufferLength++;
}
else
{
// edit/cursor position != end of buffer
// we're inserting characters at a mid-line edit position
// make room at the insert point
CmdlineBufferLength++;
for(i=CmdlineBufferLength; i>CmdlineBufferEditPos; i--)
CmdlineBuffer[i] = CmdlineBuffer[i-1];
// insert character
CmdlineBuffer[CmdlineBufferEditPos++] = c;
// repaint
cmdlineRepaint();
// reposition cursor
for(i=CmdlineBufferEditPos; i<CmdlineBufferLength; i++)
cmdlineOutputFunc(ASCII_BS);
}
}
// handle special characters
else if(c == ASCII_CR)
{
// user pressed [ENTER]
// echo CR and LF to terminal
cmdlineOutputFunc(ASCII_CR);
cmdlineOutputFunc(ASCII_LF);
// add null termination to command
CmdlineBuffer[CmdlineBufferLength++] = 0;
CmdlineBufferEditPos++;
// command is complete, process it
cmdlineProcessInputString();
// reset buffer
CmdlineBufferLength = 0;
CmdlineBufferEditPos = 0;
}
else if(c == ASCII_BS)
{
if(CmdlineBufferEditPos)
{
// is this a simple delete (off the end of the line)
if(CmdlineBufferEditPos == CmdlineBufferLength)
{
// destructive backspace
// echo backspace-space-backspace
cmdlineOutputFunc(ASCII_BS);
cmdlineOutputFunc(' ');
cmdlineOutputFunc(ASCII_BS);
// decrement our buffer length and edit position
CmdlineBufferLength--;
CmdlineBufferEditPos--;
}
else
{
// edit/cursor position != end of buffer
// we're deleting characters at a mid-line edit position
// shift characters down, effectively deleting
CmdlineBufferLength--;
CmdlineBufferEditPos--;
for(i=CmdlineBufferEditPos; i<CmdlineBufferLength; i++)
CmdlineBuffer[i] = CmdlineBuffer[i+1];
// repaint
cmdlineRepaint();
// add space to clear leftover characters
cmdlineOutputFunc(' ');
// reposition cursor
for(i=CmdlineBufferEditPos; i<(CmdlineBufferLength+1); i++)
cmdlineOutputFunc(ASCII_BS);
}
}
else
{
// else, ring the bell
cmdlineOutputFunc(ASCII_BEL);
}
}
else if(c == ASCII_DEL)
{
// not yet handled
}
else if(c == ASCII_ESC)
{
CmdlineInputVT100State = 1;
}
}
void cmdlineRepaint(void)
{
u08* ptr;
u08 i;
// carriage return
cmdlineOutputFunc(ASCII_CR);
// print fresh prompt
cmdlinePrintPrompt();
// print the new command line buffer
i = CmdlineBufferLength;
ptr = CmdlineBuffer;
while(i--) cmdlineOutputFunc(*ptr++);
}
void cmdlineDoHistory(u08 action)
{
switch(action)
{
case CMDLINE_HISTORY_SAVE:
// copy CmdlineBuffer to history if not null string
if( strlen(CmdlineBuffer) )
strcpy(CmdlineHistory[0], CmdlineBuffer);
break;
case CMDLINE_HISTORY_PREV:
// copy history to current buffer
strcpy(CmdlineBuffer, CmdlineHistory[0]);
// set the buffer position to the end of the line
CmdlineBufferLength = strlen(CmdlineBuffer);
CmdlineBufferEditPos = CmdlineBufferLength;
// "re-paint" line
cmdlineRepaint();
break;
case CMDLINE_HISTORY_NEXT:
break;
}
}
void cmdlineProcessInputString(void)
{
u08 cmdIndex;
u08 i=0;
// save command in history
cmdlineDoHistory(CMDLINE_HISTORY_SAVE);
// find the end of the command (excluding arguments)
// find first whitespace character in CmdlineBuffer
while( !((CmdlineBuffer[i] == ' ') || (CmdlineBuffer[i] == 0)) ) i++;
if(!i)
{
// command was null or empty
// output a new prompt
cmdlinePrintPrompt();
// we're done
return;
}
// search command list for match with entered command
for(cmdIndex=0; cmdIndex<CmdlineNumCommands; cmdIndex++)
{
if( !strncmp(CmdlineCommandList[cmdIndex], CmdlineBuffer, i) )
{
// user-entered command matched a command in the list (database)
// run the corresponding function
CmdlineExecFunction = CmdlineFunctionList[cmdIndex];
// new prompt will be output after user function runs
// and we're done
return;
}
}
// if we did not get a match
// output an error message
cmdlinePrintError();
// output a new prompt
cmdlinePrintPrompt();
}
void cmdlineMainLoop(void)
{
// do we have a command/function to be executed
if(CmdlineExecFunction)
{
// run it
CmdlineExecFunction();
// reset
CmdlineExecFunction = 0;
// output new prompt
cmdlinePrintPrompt();
}
}
void cmdlinePrintPrompt(void)
{
// print a new command prompt
u08* ptr = CmdlinePrompt;
while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
}
void cmdlinePrintError(void)
{
u08 * ptr;
// print a notice header
// (u08*) cast used to avoid compiler warning
ptr = (u08*)CmdlineNotice;
while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
// print the offending command
ptr = CmdlineBuffer;
while((*ptr) && (*ptr != ' ')) cmdlineOutputFunc(*ptr++);
cmdlineOutputFunc(':');
cmdlineOutputFunc(' ');
// print the not-found message
// (u08*) cast used to avoid compiler warning
ptr = (u08*)CmdlineCmdNotFound;
while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
cmdlineOutputFunc('\r');
cmdlineOutputFunc('\n');
}
// argument retrieval commands
// return string pointer to argument [argnum]
u08* cmdlineGetArgStr(u08 argnum)
{
// find the offset of argument number [argnum]
u08 idx=0;
u08 arg;
// find the first non-whitespace character
while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] == ' ')) idx++;
// we are at the first argument
for(arg=0; arg<argnum; arg++)
{
// find the next whitespace character
while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] != ' ')) idx++;
// find the first non-whitespace character
while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] == ' ')) idx++;
}
// we are at the requested argument or the end of the buffer
return &CmdlineBuffer[idx];
}
// return argument [argnum] interpreted as a decimal integer
long cmdlineGetArgInt(u08 argnum)
{
char* endptr;
return strtol(cmdlineGetArgStr(argnum), &endptr, 10);
}
// return argument [argnum] interpreted as a hex integer
long cmdlineGetArgHex(u08 argnum)
{
char* endptr;
return strtol(cmdlineGetArgStr(argnum), &endptr, 16);
}

View File

@ -1,109 +0,0 @@
/*! \file cmdline.h \brief Command-Line Interface Library. */
//*****************************************************************************
//
// File Name : 'cmdline.h'
// Title : Command-Line Interface Library
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.07.16
// Revised : 2003.07.16
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Description :
// This Command-Line interface library is meant to provide a reusable
// terminal-like user interface much like a DOS command line or UNIX terminal.
//
// The cmdline library does the following things for you:
// -Prints command prompts
// -Gathers a command string from the user (with editing features)
// -Parses the command string when the user presses [ENTER]
// -Compares the entered command to the command database
// \-Executes the corresponding function if a match is found
// \-Reports an error if no match is found
// -Provides functions to retrieve the command arguments:
// \-as strings
// \-as decimal integers
// \-as hex integers
//
// Supported editing features include:
// -Backspace support
// -Mid-line editing, inserting and deleting (left/right-arrows)
// -Command History (up-arrow) (currently only one command deep)
//
// To use the cmdline system, you will need to associate command strings
// (commands the user will be typing) with your function that you wish to have
// called when the user enters that command. This is done by using the
// cmdlineAddCommand() function.
//
// To setup the cmdline system, you must do these things:
// -Initialize it: cmdlineInit()
// -Add one or more commands to the database: cmdlineAddCommand()
// -Set an output function for your terminal: cmdlineSetOutputFunc()
//
// To operate the cmdline system, you must do these things repeatedly:
// -Pass user input from the terminal to: cmdlineSetOutputFunc()
// -Call cmdlineMainLoop() from your program's main loop
//
// The cmdline library does not assume an input or output device, but can be
// configured to use any user function for output using cmdlineSetOutputFunc()
// and accepts input by calling cmdlineInputFunc(). This means the cmdline
// library can operate over any interface including UART (serial port),
// I2c, ethernet, etc.
//
// ***** FOR MORE INFORMATION ABOUT USING cmdline SEE THE AVRLIB EXAMPLE *****
// ***** CODE IN THE avrlib/examples DIRECTORY *****
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef CMDLINE_H
#define CMDLINE_H
#include "global.h"
// constants/macros/typdefs
typedef void (*CmdlineFuncPtrType)(void);
// functions
//! initalize the command line system
void cmdlineInit(void);
//! add a new command to the database of known commands
// newCmdString should be a null-terminated command string with no whitespace
// newCmdFuncPtr should be a pointer to the function to execute when
// the user enters the corresponding command tring
void cmdlineAddCommand(u08* newCmdString, CmdlineFuncPtrType newCmdFuncPtr);
//! sets the function used for sending characters to the user terminal
void cmdlineSetOutputFunc(void (*output_func)(unsigned char c));
//! call this function to pass input charaters from the user terminal
void cmdlineInputFunc(unsigned char c);
//! call this function in your program's main loop
void cmdlineMainLoop(void);
// internal commands
void cmdlineRepaint(void);
void cmdlineDoHistory(u08 action);
void cmdlineProcessInputString(void);
void cmdlinePrintPrompt(void);
void cmdlinePrintError(void);
// argument retrieval commands
//! returns a string pointer to argument number [argnum] on the command line
u08* cmdlineGetArgStr(u08 argnum);
//! returns the decimal integer interpretation of argument number [argnum]
long cmdlineGetArgInt(u08 argnum);
//! returns the hex integer interpretation of argument number [argnum]
long cmdlineGetArgHex(u08 argnum);
#endif

View File

@ -1,44 +0,0 @@
/*! \file ataconf.h \brief IDE-ATA interface driver configuration. */
//*****************************************************************************
//
// File Name : 'ataconf.h'
// Title : IDE-ATA interface driver for hard disks
// Author : Pascal Stang - Copyright (C) 2000-2002
// Date : 11/22/2000
// Revised : 12/29/2000
// Version : 0.3
// Target MCU : Atmel AVR Series)
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef ATA_IFCONF_H
#define ATA_IFCONF_H
// constants
#define SECTOR_BUFFER_ADDR 0x1E00
// ATA register base address
#define ATA_REG_BASE 0x8000
// ATA register offset
#define ATA_REG_DATAL 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_SECCOUNT 0x02
#define ATA_REG_STARTSEC 0x03
#define ATA_REG_CYLLO 0x04
#define ATA_REG_CYLHI 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_CMDSTATUS1 0x07
#define ATA_REG_CMDSTATUS2 0x08
#define ATA_REG_ACTSTATUS 0x09
#define ATA_REG_DATAH 0x10
#endif

View File

@ -1,46 +0,0 @@
/*! \file cmdlineconf.h \brief Command-Line Interface Library Configuration. */
//*****************************************************************************
//
// File Name : 'cmdlineconf.h'
// Title : Command-Line Interface Library Configuration
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.07.16
// Revised : 2003.07.21
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef CMDLINECONF_H
#define CMDLINECONF_H
#include "global.h"
// constants/macros/typdefs
// size of command database
// (maximum number of commands the cmdline system can handle)
#define CMDLINE_MAX_COMMANDS 10
// maximum length (number of characters) of each command string
// (quantity must include one additional byte for a null terminator)
#define CMDLINE_MAX_CMD_LENGTH 15
// allotted buffer size for command entry
// (must be enough chars for typed commands and the arguments that follow)
#define CMDLINE_BUFFERSIZE 80
// number of lines of command history to keep
// (each history buffer is CMDLINE_BUFFERSIZE in size)
// ***** ONLY ONE LINE OF COMMAND HISTORY IS CURRENTLY SUPPORTED
#define CMDLINE_HISTORYSIZE 1
#endif

View File

@ -1,167 +0,0 @@
/*! \file encoderconf.h \brief Quadrature Encoder driver configuration. */
//*****************************************************************************
//
// File Name : 'encoderconf.h'
// Title : Quadrature Encoder driver configuration
// Author : Pascal Stang - Copyright (C) 2003-2004
// Created : 2003.01.26
// Revised : 2004.06.25
// Version : 0.2
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// The default number of encoders supported is 2 because most AVR processors
// have two external interrupts. To use more or fewer encoders, you must do
// four things:
//
// 1. Use a processor with at least as many external interrutps as number of
// encoders you want to have.
// 2. Set NUM_ENCODERS to the number of encoders you will use.
// 3. Comment/Uncomment the proper ENCx_SIGNAL defines for your encoders
// (the encoders must be used sequentially, 0 then 1 then 2 then 3)
// 4. Configure the various defines so that they match your processor and
// specific hardware. The notes below may help.
//
//
// -------------------- NOTES --------------------
// The external interrupt pins are mapped as follows on most AVR processors:
// (90s8515, mega161, mega163, mega323, mega16, mega32, etc)
//
// INT0 -> PD2 (PORTD, pin 2)
// INT1 -> PD3 (PORTD, pin 3)
//
// The external interrupt pins on the processors mega128 and mega64 are:
//
// INT0 -> PD0 (PORTD, pin 0)
// INT1 -> PD1 (PORTD, pin 1)
// INT2 -> PD2 (PORTD, pin 2)
// INT3 -> PD3 (PORTD, pin 3)
// INT4 -> PE4 (PORTE, pin 4)
// INT5 -> PE5 (PORTE, pin 5)
// INT6 -> PE6 (PORTE, pin 6)
// INT7 -> PE7 (PORTE, pin 7)
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef ENCODERCONF_H
#define ENCODERCONF_H
// constants/macros/typdefs
// defines for processor compatibility
// quick compatiblity for mega128, mega64
//#ifndef MCUCR
// #define MCUCR EICRA
//#endif
// Set the total number of encoders you wish to support
#define NUM_ENCODERS 2
// -------------------- Encoder 0 connections --------------------
// Phase A quadrature encoder output should connect to this interrupt line:
// *** NOTE: the choice of interrupt PORT, DDR, and PIN must match the external
// interrupt you are using on your processor. Consult the External Interrupts
// section of your processor's datasheet for more information.
// Interrupt Configuration
#define ENC0_SIGNAL SIG_INTERRUPT0 // Interrupt signal name
#define ENC0_INT INT0 // matching INTx bit in GIMSK/EIMSK
#define ENC0_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B)
#define ENC0_ISCX0 ISC00 // matching Interrupt Sense Config bit0
#define ENC0_ISCX1 ISC01 // matching Interrupt Sense Config bit1
// PhaseA Port/Pin Configuration
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC0_PHASEA_PORT PORTD // PhaseA port register
#define ENC0_PHASEA_DDR DDRD // PhaseA port direction register
#define ENC0_PHASEA_PORTIN PIND // PhaseA port input register
#define ENC0_PHASEA_PIN PD2 // PhaseA port pin
// Phase B quadrature encoder output should connect to this direction line:
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC0_PHASEB_PORT PORTC // PhaseB port register
#define ENC0_PHASEB_DDR DDRC // PhaseB port direction register
#define ENC0_PHASEB_PORTIN PINC // PhaseB port input register
#define ENC0_PHASEB_PIN PC0 // PhaseB port pin
// -------------------- Encoder 1 connections --------------------
// Phase A quadrature encoder output should connect to this interrupt line:
// *** NOTE: the choice of interrupt pin and port must match the external
// interrupt you are using on your processor. Consult the External Interrupts
// section of your processor's datasheet for more information.
// Interrupt Configuration
#define ENC1_SIGNAL SIG_INTERRUPT1 // Interrupt signal name
#define ENC1_INT INT1 // matching INTx bit in GIMSK/EIMSK
#define ENC1_ICR MCUCR // matching Int. Config Register (MCUCR,EICRA/B)
#define ENC1_ISCX0 ISC10 // matching Interrupt Sense Config bit0
#define ENC1_ISCX1 ISC11 // matching Interrupt Sense Config bit1
// PhaseA Port/Pin Configuration
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC1_PHASEA_PORT PORTD // PhaseA port register
#define ENC1_PHASEA_PORTIN PIND // PhaseA port input register
#define ENC1_PHASEA_DDR DDRD // PhaseA port direction register
#define ENC1_PHASEA_PIN PD3 // PhaseA port pin
// Phase B quadrature encoder output should connect to this direction line:
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC1_PHASEB_PORT PORTC // PhaseB port register
#define ENC1_PHASEB_DDR DDRC // PhaseB port direction register
#define ENC1_PHASEB_PORTIN PINC // PhaseB port input register
#define ENC1_PHASEB_PIN PC1 // PhaseB port pin
// -------------------- Encoder 2 connections --------------------
// Phase A quadrature encoder output should connect to this interrupt line:
// *** NOTE: the choice of interrupt pin and port must match the external
// interrupt you are using on your processor. Consult the External Interrupts
// section of your processor's datasheet for more information.
// Interrupt Configuration
//#define ENC2_SIGNAL SIG_INTERRUPT6 // Interrupt signal name
#define ENC2_INT INT6 // matching INTx bit in GIMSK/EIMSK
#define ENC2_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B)
#define ENC2_ISCX0 ISC60 // matching Interrupt Sense Config bit0
#define ENC2_ISCX1 ISC61 // matching Interrupt Sense Config bit1
// PhaseA Port/Pin Configuration
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC2_PHASEA_PORT PORTE // PhaseA port register
#define ENC2_PHASEA_PORTIN PINE // PhaseA port input register
#define ENC2_PHASEA_DDR DDRE // PhaseA port direction register
#define ENC2_PHASEA_PIN PE6 // PhaseA port pin
// Phase B quadrature encoder output should connect to this direction line:
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC2_PHASEB_PORT PORTC // PhaseB port register
#define ENC2_PHASEB_DDR DDRC // PhaseB port direction register
#define ENC2_PHASEB_PORTIN PINC // PhaseB port input register
#define ENC2_PHASEB_PIN PC2 // PhaseB port pin
// -------------------- Encoder 3 connections --------------------
// Phase A quadrature encoder output should connect to this interrupt line:
// *** NOTE: the choice of interrupt pin and port must match the external
// interrupt you are using on your processor. Consult the External Interrupts
// section of your processor's datasheet for more information.
// Interrupt Configuration
//#define ENC3_SIGNAL SIG_INTERRUPT7 // Interrupt signal name
#define ENC3_INT INT7 // matching INTx bit in GIMSK/EIMSK
#define ENC3_ICR EICRB // matching Int. Config Register (MCUCR,EICRA/B)
#define ENC3_ISCX0 ISC70 // matching Interrupt Sense Config bit0
#define ENC3_ISCX1 ISC71 // matching Interrupt Sense Config bit1
// PhaseA Port/Pin Configuration
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC3_PHASEA_PORT PORTE // PhaseA port register
#define ENC3_PHASEA_PORTIN PINE // PhaseA port input register
#define ENC3_PHASEA_DDR DDRE // PhaseA port direction register
#define ENC3_PHASEA_PIN PE7 // PhaseA port pin
// Phase B quadrature encoder output should connect to this direction line:
// *** PORTx, DDRx, PINx, and Pxn should all have the same letter for "x" ***
#define ENC3_PHASEB_PORT PORTC // PhaseB port register
#define ENC3_PHASEB_DDR DDRC // PhaseB port direction register
#define ENC3_PHASEB_PORTIN PINC // PhaseB port input register
#define ENC3_PHASEB_PIN PC3 // PhaseB port pin
#endif

View File

@ -1,40 +0,0 @@
/*! \file fatconf.h \brief FAT16/32 file system driver configuration. */
//*****************************************************************************
//
// File Name : 'fatconf.h'
// Title : FAT16/32 file system driver configuration
// Author : Pascal Stang
// Date : 4/19/2003
// Revised : 4/19/2003
// Version : 0.3
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef FATCONF_H
#define FATCONF_H
// debug on/off
#define DEBUG_FAT
#define SECTOR_BUFFER1_ADDR 0x0600+0x0600
#define SECTOR_BUFFER1_SIZE 0x0200
#define LONGNAME_BUFFER_ADDR 0x0200+0x0600
#define LONGNAME_BUFFER_SIZE 0x0100
#define DIRNAME_BUFFER_ADDR 0x0300+0x0600
#define DIRNAME_BUFFER_SIZE 0x0100
#define FAT_CACHE_ADDR 0x0400+0x0600
#define FAT_CACHE_SIZE 0x0200
#endif

View File

@ -1,40 +0,0 @@
/*! \file global.h \brief AVRlib project global include. */
//*****************************************************************************
//
// File Name : 'global.h'
// Title : AVRlib project global include
// Author : Pascal Stang - Copyright (C) 2001-2002
// Created : 7/12/2001
// Revised : 9/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This include file is designed to contain items useful to all
// code files and projects.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef GLOBAL_H
#define GLOBAL_H
// global AVRLIB defines
#include "avrlibdefs.h"
// global AVRLIB types definitions
#include "avrlibtypes.h"
// project/system dependent defines
// CPU clock speed
//#define F_CPU 16000000 // 16MHz processor
//#define F_CPU 14745000 // 14.745MHz processor
//#define F_CPU 8000000 // 8MHz processor
#define F_CPU 7372800 // 7.37MHz processor
//#define F_CPU 4000000 // 4MHz processor
//#define F_CPU 3686400 // 3.69MHz processor
#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
#endif

View File

@ -1,28 +0,0 @@
/*! \file i2cconf.h \brief I2C (TWI) interface configuration. */
//*****************************************************************************
//
// File Name : 'i2cconf.h'
// Title : I2C (TWI) interface configuration
// Author : Pascal Stang - Copyright (C) 2002-2003
// Created : 2002.06.25
// Revised : 2003.03.02
// Version : 0.7
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef I2CCONF_H
#define I2CCONF_H
// define I2C data buffer sizes
// These buffers are used in interrupt-driven Master sending and receiving,
// and in slave sending and receiving. They must be large enough to store
// the largest I2C packet you expect to send and receive, respectively.
#define I2C_SEND_DATA_BUFFER_SIZE 0x20
#define I2C_RECEIVE_DATA_BUFFER_SIZE 0x20
#endif

View File

@ -1,32 +0,0 @@
/*! \file i2cswconf.h \brief Software-driven I2C interface configuration. */
//*****************************************************************************
//
// File Name : 'i2cswconf.h'
// Title : software-driven I2C interface using port pins
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 11/22/2000
// Revised : 5/2/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef I2CSWCONF_H
#define I2CSWCONF_H
// clock line port
#define SCLPORT PORTD // i2c clock port
#define SCLDDR DDRD // i2c clock port direction
// data line port
#define SDAPORT PORTD // i2c data port
#define SDADDR DDRD // i2c data port direction
#define SDAPIN PIND // i2c data port input
// pin assignments
#define SCL PD0 // i2c clock pin
#define SDA PD1 // i2c data pin
#endif

View File

@ -1,85 +0,0 @@
/*! \file ks0108conf.h \brief Graphic LCD driver configuration. */
//*****************************************************************************
//
// File Name : 'ks0108conf.h'
// Title : Graphic LCD driver for HD61202/KS0108 displays
// Author : Pascal Stang - Copyright (C) 2001-2003
// Date : 10/19/2001
// Revised : 5/1/2003
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef KS0108CONF_H
#define KS0108CONF_H
// define LCD hardware interface
// -LCD_MEMORY_INTERFACE assumes that the registers of the LCD have been mapped
// into the external memory space of the AVR processor memory bus
// -LCD_PORT_INTERFACE is a direct-connection interface from port pins to LCD
// SELECT (UNCOMMENT) ONLY ONE!
// *** NOTE: memory interface is not yet fully supported, but it might work
//#define GLCD_MEMORY_INTERFACE
#define GLCD_PORT_INTERFACE
// GLCD_PORT_INTERFACE specifics
#ifdef GLCD_PORT_INTERFACE
// make sure these parameters are not already defined elsewhere
#ifndef GLCD_CTRL_PORT
#define GLCD_CTRL_PORT PORTB // PORT for LCD control signals
#define GLCD_CTRL_DDR DDRB // DDR register of LCD_CTRL_PORT
#define GLCD_CTRL_RS PB0 // pin for LCD Register Select
#define GLCD_CTRL_RW PB1 // pin for LCD Read/Write
#define GLCD_CTRL_E PB2 // pin for LCD Enable
#define GLCD_CTRL_CS0 PB3 // pin for LCD Controller 0 Chip Select
#define GLCD_CTRL_CS1 PB4 // pin for LCD Controller 1 Chip Select(*)
#define GLCD_CTRL_CS2 PB6 // pin for LCD Controller 2 Chip Select(*)
#define GLCD_CTRL_CS3 PB7 // pin for LCD Controller 3 Chip Select(*)
#define GLCD_CTRL_RESET PB5 // pin for LCD Reset
// (*) NOTE: additonal controller chip selects are optional and
// will be automatically used per each step in 64 pixels of display size
// Example: Display with 128 hozizontal pixels uses 2 controllers
#endif
#ifndef GLCD_DATA_PORT
#define GLCD_DATA_PORT PORTC // PORT for LCD data signals
#define GLCD_DATA_DDR DDRC // DDR register of LCD_DATA_PORT
#define GLCD_DATA_PIN PINC // PIN register of LCD_DATA_PORT
#endif
#endif
// GLCD_MEMORY_INTERFACE specifics
#ifdef GLCD_MEMORY_INTERFACE
// make sure these parameters are not already defined elsewhere
#ifndef GLCD_CONTROLLER0_CTRL_ADDR
// absolute address of LCD Controller #0 CTRL and DATA registers
#define GLCD_CONTROLLER0_CTRL_ADDR 0x1000
#define GLCD_CONTROLLER0_DATA_ADDR 0x1001
// offset of other controllers with respect to controller0
#define GLCD_CONTROLLER_ADDR_OFFSET 0x0002
#endif
#endif
// LCD geometry defines (change these definitions to adapt code/settings)
#define GLCD_XPIXELS 128 // pixel width of entire display
#define GLCD_YPIXELS 64 // pixel height of entire display
#define GLCD_CONTROLLER_XPIXELS 64 // pixel width of one display controller
// Set text size of display
// These definitions are not currently used and will probably move to glcd.h
#define GLCD_TEXT_LINES 8 // visible lines
#define GLCD_TEXT_LINE_LENGTH 22 // internal line length
#endif

View File

@ -1,97 +0,0 @@
/*! \file lcdconf.h \brief Character LCD driver configuration. */
//*****************************************************************************
//
// File Name : 'lcdconf.h'
// Title : Character LCD driver for HD44780/SED1278 displays
// (usable in mem-mapped, or I/O mode)
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 11/22/2000
// Revised : 4/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef LCDCONF_H
#define LCDCONF_H
// Define type of interface used to access the LCD
// LCD_MEMORY_INTERFACE:
// To use this mode you must supply the necessary hardware to connect the
// LCD to the CPU's memory bus. The CONTROL and DATA registers of the LCD
// (HD44780 chip) must appear in the CPU's memory map. This mode is faster
// than the port interface but requires a little extra hardware to make it
// work. It is especially useful when your CPU is already configured to
// use an external memory bus for other purposes (like accessing memory).
//
// LCD_PORT_INTERFACE:
// This mode allows you to connect the control and data lines of the LCD
// directly to the I/O port pins (no interfacing hardware is needed),
// but it generally runs slower than the LCD_MEMORY_INTERFACE.
// Depending on your needs, when using the LCD_PORT_INTERFACE, the LCD may
// be accessed in 8-bit or 4-bit mode. In 8-bit mode, one whole I/O port
// (pins 0-7) is required for the LCD data lines, but transfers are faster.
// In 4-bit mode, only I/O port pins 4-7 are needed for data lines, but LCD
// access is slower. In either mode, three additional port pins are
// required for the LCD interface control lines (RS, R/W, and E).
// Enable one of the following interfaces to your LCD
//#define LCD_MEMORY_INTERFACE
#define LCD_PORT_INTERFACE
// Enter the parameters for your chosen interface'
// if you chose the LCD_PORT_INTERFACE:
#ifdef LCD_PORT_INTERFACE
#ifndef LCD_CTRL_PORT
// port and pins you will use for control lines
#define LCD_CTRL_PORT PORTC
#define LCD_CTRL_DDR DDRC
#define LCD_CTRL_RS 2
#define LCD_CTRL_RW 3
#define LCD_CTRL_E 4
#endif
#ifndef LCD_DATA_POUT
// port you will use for data lines
#define LCD_DATA_POUT PORTA
#define LCD_DATA_PIN PINA
#define LCD_DATA_DDR DDRA
// access mode you will use (default is 8bit unless 4bit is selected)
//#define LCD_DATA_4BIT
#endif
#endif
// if you chose the LCD_MEMORY_INTERFACE:
#ifdef LCD_MEMORY_INTERFACE
#ifndef LCD_CTRL_ADDR
// CPU memory address of the LCD control register
#define LCD_CTRL_ADDR 0x1000
#endif
#ifndef LCD_DATA_ADDR
// CPU memory address of the LCD data register
#define LCD_DATA_ADDR 0x1001
#endif
#endif
// LCD display geometry
// change these definitions to adapt settings
#define LCD_LINES 4 // visible lines
#define LCD_LINE_LENGTH 20 // line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR 0x00
#define LCD_LINE1_DDRAMADDR 0x40
#define LCD_LINE2_DDRAMADDR 0x14
#define LCD_LINE3_DDRAMADDR 0x54
// LCD delay
// This delay affects how quickly accesses are made to the LCD controller.
// If your clock frequency is low, you can reduce the number of NOPs in the
// delay. If your clock frequency is high, you may need to add NOPs.
// The number of NOPs should be between at least 1 and up to 20.
#define LCD_DELAY asm volatile ("nop\n nop\n nop\n nop\n");
#endif

View File

@ -1,33 +0,0 @@
/*! \file mmcconf.h \brief MultiMedia and SD Flash Card Interface Configuration. */
//*****************************************************************************
//
// File Name : 'mmc.h'
// Title : MultiMedia and SD Flash Card Interface Configuration
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.09.22
// Revised : 2004.09.22
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef MMCCONF_H
#define MMCCONF_H
// define to enable debugging print statements
//#define MMC_DEBUG
// MMC card chip select pin defines
#define MMC_CS_PORT PORTB
#define MMC_CS_DDR DDRB
#define MMC_CS_PIN 0
#endif

View File

@ -1,24 +0,0 @@
--- AVRlib "conf" files ---
AVRlib contains many function/code libraries which depend upon particular aspects of the
user's hardware. The most basic of these is the processor clock rate. The clock rate defines
dozens of aspects of processor operation from code delays to UART baud rates.
To allow AVRlib to work easily with hardware that may vary from project to project, all
user-configurable parameters of AVRlib are contained in the template configuration files in
this directory. NOTE that these files are only templates and should be copied, as needed,
to an individual project's code directory and edited to suit that project's hardware.
global.h is the only configuration include file that is common to the entire AVRlib code base.
To use AVRlib libraries, you must copy global.h to your project's code directory and modify
the options inside global.h to match your hardware.) Each project should have its own global.h.
Other *conf.h files should be copied to your project's code directory as needed. For example,
if you intend to use the lcd.c library, you will need to copy lcdconf.h and modify it to match
the I/O and LCD configuration of your hardware.
** If you fail to copy the configuration files needed for the AVRlib libraries you use,
the problem will usually exhibit itself as a compile-time error.

View File

@ -1,82 +0,0 @@
/*! \file servoconf.h \brief Interrupt-driven RC Servo configuration. */
//*****************************************************************************
//
// File Name : 'servoconf.h'
// Title : Interrupt-driven RC Servo function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 07/31/2002
// Revised : 09/30/2002
// Version : 1.0
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: you need the latest version (3.2+) of the AVR-GCC compiler to use this
// function library. Download it from http://www.avrfreaks.net/AVRGCC
//
// Description : This code allows you to drive up to 8 RC servos from any
// combination of ports and pins on the AVR processor. Using interrupts,
// this code continuously sends control signals to the servo to maintain
// position even while your code is doing other work.
//
// The servoInit and servoOff effectively turn on and turn off servo
// control. When you run ServoInit, it automatically assigns each
// "channel" of servo control to be output on the SERVO_DEFAULT_PORT.
// One "channel" of servo control can control one servo and must be
// assigned single I/O pin for output.
//
// If you're using all eight channels (SERVO_NUM_CHANNELS = 8), then
// then by default the code will use SERVO_DEFAULT_PORT pins 0-7.
// If you're only using four channels, then pins 0-3 will be used by
// default.
//
// The command servoSetChannelIO(channel, port, pin) allows you to
// reassign the output of any channel to any port and I/O pin you
// choose. For exampe, if you have an RC servo connected to PORTC, pin 6,
// and you wish to use channel 2 to control it, use:
//
// servoSerChannelIO( 2, _SFR_IO_ADDR(PORTC), 6)
//
// (NOTE: you must include the "_SRF_IO_ADDR()" part around your port)
//
// The servoSetPostion and servoGetPosition commands allow you to command
// a given servo to your desired position. The position you request must
// lie between the SERVO_MIN and SERVO_MAX limit you defined.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef SERVOCONF_H
#define SERVOCONF_H
// set number of servo channels (1 to 8)
// This is the number of servos you would like to drive
// Each "Channel" can control one servo and by default will
// map directly to the port pin of the same number on the
// SERVO_DEFAULT_PORT. You can change this default port/pin
// assignment for a given channel to any port/pin you like.
// See the "servoSetChannelIO" function.
#define SERVO_NUM_CHANNELS 4
// set default SERVO output port
// This is the AVR port which you have connected to your servos
// See top of file for how servo "channels" map to port pins
#define SERVO_DEFAULT_PORT PORTB
// set servo characteristics (min and max raw position)
// You must find these by testing using your brand/type of servos.
// The min/max settings will change proportional to F_CPU, the CPU
// clock frequency.
// The numbers below good for parallax servos at an F_CPU of ~8MHz.
//#define SERVO_MAX 71
//#define SERVO_MIN 17
// The numbers below good for parallax servos at an F_CPU of ~14.745MHz.
#define SERVO_MAX 138
#define SERVO_MIN 34
// set servo scaled range
// This sets the scaled position range of the servo. Allowed scaled
// positions are 0 -> SERVO_POSITION_MAX, and correspond to raw
// positions of SERVO_MIN -> SERVO_MAX.
#define SERVO_POSITION_MAX 255
#endif

View File

@ -1,42 +0,0 @@
/*! \file sramswconf.h \brief Software-driven SRAM memory bus access configuration. */
//*****************************************************************************
//
// File Name : 'sramswconf.h'
// Title : Software-driven SRAM memory bus access functions
// Author : Pascal Stang - Copyright (C) 2002
// Created : 11/11/2002
// Revised : 11/13/2002
// Version : 1.0
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef SRAMSWCONF_H
#define SRAMSWCONF_H
// defines
// data bus (DATA[0:7]) and low address (ADDR[0:7]) port
#define SRAM_ADL PORTA
#define SRAM_ADL_DDR DDRA
#define SRAM_ADL_IN PINA
// high address port (ADDR[8:15])
#define SRAM_AH PORTC
#define SRAM_AH_DDR DDRC
// page address port (PAGE[0:3])
#define SRAM_PAGE PORTB
#define SRAM_PAGE_DDR DDRB
#define SRAM_PAGE_MASK 0x0F
// control port
#define SRAM_CTRL PORTD
#define SRAM_CTRL_DDR DDRD
// control lines
#define SRAM_ALE PD5
#define SRAM_WR PD6
#define SRAM_RD PD7
#endif

View File

@ -1,34 +0,0 @@
/*! \file sta013conf.h \brief STA013 MP3 player driver configuration. */
//*****************************************************************************
//
// File Name : 'sta013.h'
// Title : STMicroelectronics STA013 MP3 player driver
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 10/22/2000
// Revised : 12/04/2000
// Version : 0.3
// Target MCU : ATmega103 (should work for Atmel AVR Series)
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef STA013CONF_H
#define STA013CONF_H
// STA013 Configuration
// STA013 demand line
#define STA013_DEMAND_PORT PORTE // port to which DEMAND line is connected
#define STA013_DEMAND_PORTIN PINE // input port to which DEMAND line is connected
#define STA013_DEMAND_PIN PE4 // port pin to which DEMAND line is connected
#define STA013_DEMAND_INTR SIG_INTERRUPT4 // interrupt to which DEMAND line is connected
#endif

View File

@ -1,28 +0,0 @@
/*! \file stxetxconf.h \brief STX/ETX Packet Protocol Implementation Configuration. */
//*****************************************************************************
//
// File Name : 'stxetx.h'
// Title : STX/ETX Packet Protocol Implementation Configuration
// Author : Pascal Stang - Copyright (C) 2002-2003
// Created : 10/9/2002
// Revised : 02/10/2003
// Version : 0.1
// Target MCU : any
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef STXETXCONF_H
#define STXETXCONF_H
// STX/ETX Configuration Options
// This determines the size of the Packet Receive Buffer
// where whole verified packets are copied after being received
#define STXETX_MAXRXPACKETSIZE 20 // length of packet buffer
#endif

View File

@ -1,68 +0,0 @@
/*! \file uartsw2conf.h \brief Interrupt-driven Software UART Driver Configuration. */
//*****************************************************************************
//
// File Name : 'uartsw2conf.h'
// Title : Interrupt-driven Software UART Driver Configuration
// Author : Pascal Stang - Copyright (C) 2002-2003
// Created : 7/20/2002
// Revised : 4/27/2004
// Version : 0.6
// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32)
// Editor Tabs : 4
//
// Description :
// This uart library emulates the operation of a UART (serial port) using
// the AVR's hardware timers, I/O pins, and some software.
//
// Specifically, this code uses:
// -Timer 2 Output Capture for transmit timing
// -Timer 0 Output Capture for receive timing
// -External Interrupt 2 for receive triggering
//
// The above resources cannot be used for other purposes while this software
// UART is enabled. The overflow interrupts from Timer0 and Timer2 can still
// be used for other timing, but the prescalers for these timers must not be
// changed.
//
// Serial output from this UART can be routed to any I/O pin. Serial input
// for this UART must come from the External Interrupt 2 (INT2) I/O pin.
// These options should be configured by editing your local copy of
// "uartsw2conf.h".
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef UARTSW2CONF_H
#define UARTSW2CONF_H
// constants/macros/typdefs
#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes
#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals
// when non-inverted, the serial line is appropriate for passing though
// an RS232 driver like the MAX232. When inverted, the serial line can
// directly drive/receive RS232 signals to/from a DB9 connector. Be sure
// to use a current-limiting resistor and perhaps a diode-clamp circuit when
// connecting incoming RS232 signals to a microprocessor I/O pin.
// if non-inverted, the serial line idles high (logic 1) between bytes
// if inverted, the serial line idles low (logic 0) between bytes
// UART transmit pin defines
#define UARTSW_TX_PORT PORTB ///< UART Transmit Port
#define UARTSW_TX_DDR DDRB ///< UART Transmit DDR
#define UARTSW_TX_PIN PB3 ///< UART Transmit Pin
// UART receive pin defines
// This pin must correspond to the
// External Interrupt 2 (INT2) pin for your processor
#define UARTSW_RX_PORT PORTB ///< UART Receive Port
#define UARTSW_RX_DDR DDRB ///< UART Receive DDR
#define UARTSW_RX_PORTIN PINB ///< UART Receive Port Input
#define UARTSW_RX_PIN PB2 ///< UART Receive Pin
#endif

View File

@ -1,67 +0,0 @@
/*! \file uartswconf.h \brief Interrupt-driven Software UART Driver Configuration. */
//*****************************************************************************
//
// File Name : 'uartswconf.h'
// Title : Interrupt-driven Software UART Driver Configuration
// Author : Pascal Stang - Copyright (C) 2002-2004
// Created : 7/20/2002
// Revised : 4/27/2004
// Version : 0.1
// Target MCU : Atmel AVR Series (intended for the ATmega16 and ATmega32)
// Editor Tabs : 4
//
// Description :
// This uart library emulates the operation of a UART (serial port) using
// the AVR's hardware timers, I/O pins, and some software.
//
// Specifically, this code uses:
// -Timer 1 Output Compare A for transmit timing
// -Timer 1 Output Compare B for receive timing
// -Timer 1 Input Capture for receive triggering
//
// The above resources cannot be used for other purposes while this software
// UART is enabled. The overflow interrupt from Timer1 can still be used for
// other timing, but the prescaler for Timer1 must not be changed.
//
// Serial output from this UART can be routed to any I/O pin. Serial input
// for this UART must come from the Timer1 Input Capture (IC1) I/O pin.
// These options should be configured by editing your local copy of
// "uartswconf.h".
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef UARTSWCONF_H
#define UARTSWCONF_H
// constants/macros/typdefs
#define UARTSW_RX_BUFFER_SIZE 0x20 ///< UART receive buffer size in bytes
#define UARTSW_INVERT ///< define to invert polarity of RX/TX signals
// when non-inverted, the serial line is appropriate for passing though
// an RS232 driver like the MAX232. When inverted, the serial line can
// directly drive/receive RS232 signals to/from a DB9 connector. Be sure
// to use a current-limiting resistor and perhaps a diode-clamp circuit when
// connecting incoming RS232 signals to a microprocessor I/O pin.
// if non-inverted, the serial line idles high (logic 1) between bytes
// if inverted, the serial line idles low (logic 0) between bytes
// UART transmit pin defines
#define UARTSW_TX_PORT PORTD ///< UART Transmit Port
#define UARTSW_TX_DDR DDRD ///< UART Transmit DDR
#define UARTSW_TX_PIN PD5 ///< UART Transmit Pin
// UART receive pin defines
// This pin must correspond to the
// Timer1 Input Capture (ICP or IC1) pin for your processor
#define UARTSW_RX_PORT PORTD ///< UART Receive Port
#define UARTSW_RX_DDR DDRD ///< UART Receive DDR
#define UARTSW_RX_PORTIN PIND ///< UART Receive Port Input
#define UARTSW_RX_PIN PD6 ///< UART Receive Pin
#endif

View File

@ -1,99 +0,0 @@
/*! \file debug.c \brief Debugging function library. */
//*****************************************************************************
//
// File Name : 'debug.c'
// Title : Helpful debugging functions
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003-03-13
// Revised : 2003-03-13
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This file contains a set of functions which may be useful
// for general debugging.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "debug.h"
#include "rprintf.h" // include printf support
// global variables
// functions
// Print a part of memory as a formatted hex table with ascii translation
void debugPrintHexTable(u16 length, u08 *buffer)
{
u08 i;
u16 j;
u08 *buf;
u08 s;
buf = buffer;
// print the low order address indicies and ASCII header
rprintfProgStrM(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n");
rprintfProgStrM(" ----------------------------------------------- ---- ASCII -----\r\n");
// print the data
for(j=0; j<((length+15)>>4); j++)
{
// print the high order address index for this line
rprintfu16(j<<4);
rprintfChar(' ');
// print the hex data
for(i=0; i<0x10; i++)
{
// be nice and print only up to the exact end of the data
if( ((j<<4)+i) < length)
{
// print hex byte
rprintfu08(buf[(j<<4)+i]);
rprintfChar(' ');
}
else
{
// we're past the end of the data's length
// print spaces
rprintfProgStrM(" ");
}
}
// leave some space
rprintfChar(' ');
// print the ascii data
for(i=0; i<0x10; i++)
{
// be nice and print only up to the exact end of the data
if( ((j<<4)+i) < length)
{
// get the character
s = buf[(j<<4)+i];
// make sure character is printable
if(s >= 0x20)
rprintfChar(s);
else
rprintfChar('.');
}
else
{
// we're past the end of the data's length
// print a space
rprintfChar(' ');
}
}
rprintfCRLF();
}
}

View File

@ -1,34 +0,0 @@
/*! \file debug.h \brief Debugging function library. */
//*****************************************************************************
//
// File Name : 'debug.h'
// Title : Helpful debugging functions
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003-03-13
// Revised : 2003-03-13
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This file contains a set of functions which may be useful
// for general debugging.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef DEBUG_H
#define DEBUG_H
#include "global.h"
// defines
// function prototypes
//! Print a part of memory as a formatted hex table with ascii translation
void debugPrintHexTable(u16 length, u08 *buffer);
#endif

View File

@ -1,147 +0,0 @@
/*! \file ds1631.c \brief Dallas DS1631 Temperature Sensor Driver Library. */
//*****************************************************************************
//
// File Name : 'ds1631.c'
// Title : Dallas DS1631 Temperature Sensor Driver Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.02.10
// Revised : 2004.02.19
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "timer.h"
#include "i2c.h"
#include "ds1631.h"
// global variables
// Functions
u08 ds1631Init(u08 i2cAddr)
{
u08 chip_ok;
// issue a reset
if(ds1631Reset(i2cAddr) == I2C_OK)
chip_ok = TRUE;
else
chip_ok = FALSE;
// set a default configuration
// (1-shot mode, T_OUT active high, and 12-bit conversion)
ds1631SetConfig(i2cAddr,
DS1631_CONFIG_1SHOT | DS1631_CONFIG_POL |
DS1631_CONFIG_R0 | DS1631_CONFIG_R1);
return chip_ok;
}
u08 ds1631Reset(u08 i2cAddr)
{
u08 buffer[1];
// return the DS1631 to power-on reset defaults
buffer[0] = DS1631_CMD_SWPOR;
return i2cMasterSendNI(i2cAddr, 1, buffer);
}
void ds1631SetConfig(u08 i2cAddr, u08 config)
{
u08 buffer[2];
// write the DS1631 configuration byte
buffer[0] = DS1631_CMD_ACCESSCONFIG;
buffer[1] = config;
i2cMasterSendNI(i2cAddr, 2, buffer);
}
u08 ds1631GetConfig(u08 i2cAddr)
{
u08 buffer[1];
// write the DS1631 configuration byte
buffer[0] = DS1631_CMD_ACCESSCONFIG;
i2cMasterSendNI(i2cAddr, 2, buffer);
i2cMasterReceiveNI(i2cAddr, 2, buffer);
return buffer[0];
}
void ds1631StartConvert(u08 i2cAddr)
{
u08 buffer[1];
// send the DS1631 Start Convert command
buffer[0] = DS1631_CMD_STARTCONV;
i2cMasterSendNI(i2cAddr, 1, buffer);
}
void ds1631StopConvert(u08 i2cAddr)
{
u08 buffer[1];
// send the DS1631 Stop Convert command
buffer[0] = DS1631_CMD_STOPCONV;
i2cMasterSendNI(i2cAddr, 1, buffer);
}
s16 ds1631ReadTemp(u08 i2cAddr)
{
// read the Temperature register and return the result
return ds1631ReadTempReg(i2cAddr, DS1631_CMD_READTEMP);
}
void ds1631SetTH(u08 i2cAddr, s16 value)
{
// write the TH register
ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTH, value);
}
void ds1631SetTL(u08 i2cAddr, s16 value)
{
// write the TL register
ds1631WriteTempReg(i2cAddr, DS1631_CMD_ACCESSTL, value);
}
s16 ds1631GetTH(u08 i2cAddr)
{
// read the TH register and return the result
return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTH);
}
s16 ds1631GetTL(u08 i2cAddr)
{
// read the TL register and return the result
return ds1631ReadTempReg(i2cAddr, DS1631_CMD_ACCESSTL);
}
s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd)
{
u08 buffer[2];
s16 T;
// read the temperature value from the requested register
i2cMasterSendNI(i2cAddr, 1, &cmd);
i2cMasterReceiveNI(i2cAddr, 2, buffer);
// pack bytes
T = (s16)((buffer[0]<<8) | buffer[1]);
// return result
return T;
}
void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value)
{
u08 buffer[3];
// write the requested register with a temperature value
buffer[0] = cmd;
buffer[1] = value>>8;
buffer[2] = value;
i2cMasterSendNI(i2cAddr, 3, buffer);
}

View File

@ -1,86 +0,0 @@
/*! \file ds1631.h \brief Dallas DS1631 Temperature Sensor Driver Library. */
//*****************************************************************************
//
// File Name : 'ds1631.h'
// Title : Dallas DS1631 Temperature Sensor Driver Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.02.10
// Revised : 2004.02.19
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef DS1631_H
#define DS1631_H
#include "global.h"
// constants/macros/typdefs
#define DS1631_I2C_ADDR 0x90 //< Base I2C address of DS1631 devices
#define DS1631_CMD_STARTCONV 0x51 //< DS1631 Start conversion command byte
#define DS1631_CMD_STOPCONV 0x22 //< DS1631 Stop conversion command byte
#define DS1631_CMD_READTEMP 0xAA //< DS1631 Read Temperature command byte
#define DS1631_CMD_ACCESSTH 0xA1 //< DS1631 TH read/write command byte
#define DS1631_CMD_ACCESSTL 0xA2 //< DS1631 TL read/write command byte
#define DS1631_CMD_ACCESSCONFIG 0xAC //< DS1631 Config read/write command byte
#define DS1631_CMD_SWPOR 0x54 //< DS1631 Software Reset command byte
#define DS1631_CONFIG_1SHOT 0x01
#define DS1631_CONFIG_POL 0x02
#define DS1631_CONFIG_R0 0x04
#define DS1631_CONFIG_R1 0x08
#define DS1631_CONFIG_NVB 0x10
#define DS1631_CONFIG_TLF 0x20
#define DS1631_CONFIG_THF 0x40
#define DS1631_CONFIG_DONE 0x80
// functions
//! Initialize the DS1631 chip
u08 ds1631Init(u08 i2cAddr);
//! Reset the DS1631 chip to its power-on defaults
u08 ds1631Reset(u08 i2cAddr);
//! Set the configuration byte of the DS1631
void ds1631SetConfig(u08 i2cAddr, u08 config);
//! Get the configuration byte of the DS1631
u08 ds1631GetConfig(u08 i2cAddr);
//! Start a temperature conversion
void ds1631StartConvert(u08 i2cAddr);
//! Stop a temperature conversion (or stop continuous conversion mode)
void ds1631StopConvert(u08 i2cAddr);
//! Read the result of a temperature conversion
s16 ds1631ReadTemp(u08 i2cAddr);
//! Set the Temp-High threshold
void ds1631SetTH(u08 i2cAddr, s16 value);
//! Set the Temp-Low threshold
void ds1631SetTL(u08 i2cAddr, s16 value);
//! Get the Temp-High threshold
s16 ds1631GetTH(u08 i2cAddr);
//! Get the Temp-Low threshold
s16 ds1631GetTL(u08 i2cAddr);
void ds1631WriteTempReg(u08 i2cAddr, u08 cmd, s16 value);
s16 ds1631ReadTempReg(u08 i2cAddr, u08 cmd);
#endif

View File

@ -1,229 +0,0 @@
/*! \file encoder.c \brief Quadrature Encoder reader/driver. */
//*****************************************************************************
//
// File Name : 'encoder.c'
// Title : Quadrature Encoder reader/driver
// Author : Pascal Stang - Copyright (C) 2003-2004
// Created : 2003.01.26
// Revised : 2004.06.25
// Version : 0.3
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#endif
#include "global.h"
#include "encoder.h"
// Program ROM constants
// Global variables
volatile EncoderStateType EncoderState[NUM_ENCODERS];
// Functions
// encoderInit() initializes hardware and encoder position readings
// Run this init routine once before using any other encoder functions.
void encoderInit(void)
{
u08 i;
// initialize/clear encoder data
for(i=0; i<NUM_ENCODERS; i++)
{
EncoderState[i].position = 0;
//EncoderState[i].velocity = 0; // NOT CURRENTLY USED
}
// configure direction and interrupt I/O pins:
// - for input
// - apply pullup resistors
// - any-edge interrupt triggering
// - enable interrupt
#ifdef ENC0_SIGNAL
// set interrupt pins to input and apply pullup resistor
cbi(ENC0_PHASEA_DDR, ENC0_PHASEA_PIN);
sbi(ENC0_PHASEA_PORT, ENC0_PHASEA_PIN);
// set encoder direction pin for input and apply pullup resistor
cbi(ENC0_PHASEB_DDR, ENC0_PHASEB_PIN);
sbi(ENC0_PHASEB_PORT, ENC0_PHASEB_PIN);
// configure interrupts for any-edge triggering
sbi(ENC0_ICR, ENC0_ISCX0);
cbi(ENC0_ICR, ENC0_ISCX1);
// enable interrupts
sbi(IMSK, ENC0_INT); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC1_SIGNAL
// set interrupt pins to input and apply pullup resistor
cbi(ENC1_PHASEA_DDR, ENC1_PHASEA_PIN);
sbi(ENC1_PHASEA_PORT, ENC1_PHASEA_PIN);
// set encoder direction pin for input and apply pullup resistor
cbi(ENC1_PHASEB_DDR, ENC1_PHASEB_PIN);
sbi(ENC1_PHASEB_PORT, ENC1_PHASEB_PIN);
// configure interrupts for any-edge triggering
sbi(ENC1_ICR, ENC1_ISCX0);
cbi(ENC1_ICR, ENC1_ISCX1);
// enable interrupts
sbi(IMSK, ENC1_INT); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC2_SIGNAL
// set interrupt pins to input and apply pullup resistor
cbi(ENC2_PHASEA_DDR, ENC2_PHASEA_PIN);
sbi(ENC2_PHASEA_PORT, ENC2_PHASEA_PIN);
// set encoder direction pin for input and apply pullup resistor
cbi(ENC2_PHASEB_DDR, ENC2_PHASEB_PIN);
sbi(ENC2_PHASEB_PORT, ENC2_PHASEB_PIN);
// configure interrupts for any-edge triggering
sbi(ENC2_ICR, ENC2_ISCX0);
cbi(ENC2_ICR, ENC2_ISCX1);
// enable interrupts
sbi(IMSK, ENC2_INT); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC3_SIGNAL
// set interrupt pins to input and apply pullup resistor
cbi(ENC3_PHASEA_DDR, ENC3_PHASEA_PIN);
sbi(ENC3_PHASEA_PORT, ENC3_PHASEA_PIN);
// set encoder direction pin for input and apply pullup resistor
cbi(ENC3_PHASEB_DDR, ENC3_PHASEB_PIN);
sbi(ENC3_PHASEB_PORT, ENC3_PHASEB_PIN);
// configure interrupts for any-edge triggering
sbi(ENC3_ICR, ENC3_ISCX0);
cbi(ENC3_ICR, ENC3_ISCX1);
// enable interrupts
sbi(IMSK, ENC3_INT); // ISMK is auto-defined in encoder.h
#endif
// enable global interrupts
sei();
}
// encoderOff() disables hardware and stops encoder position updates
void encoderOff(void)
{
// disable encoder interrupts
#ifdef ENC0_SIGNAL
// disable interrupts
sbi(IMSK, INT0); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC1_SIGNAL
// disable interrupts
sbi(IMSK, INT1); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC2_SIGNAL
// disable interrupts
sbi(IMSK, INT2); // ISMK is auto-defined in encoder.h
#endif
#ifdef ENC3_SIGNAL
// disable interrupts
sbi(IMSK, INT3); // ISMK is auto-defined in encoder.h
#endif
}
// encoderGetPosition() reads the current position of the encoder
s32 encoderGetPosition(u08 encoderNum)
{
// sanity check
if(encoderNum < NUM_ENCODERS)
return EncoderState[encoderNum].position;
else
return 0;
}
// encoderSetPosition() sets the current position of the encoder
void encoderSetPosition(u08 encoderNum, s32 position)
{
// sanity check
if(encoderNum < NUM_ENCODERS)
EncoderState[encoderNum].position = position;
// else do nothing
}
#ifdef ENC0_SIGNAL
//! Encoder 0 interrupt handler
SIGNAL(ENC0_SIGNAL)
{
// encoder has generated a pulse
// check the relative phase of the input channels
// and update position accordingly
if( ((inb(ENC0_PHASEA_PORTIN) & (1<<ENC0_PHASEA_PIN)) == 0) ^
((inb(ENC0_PHASEB_PORTIN) & (1<<ENC0_PHASEB_PIN)) == 0) )
{
EncoderState[0].position++;
}
else
{
EncoderState[0].position--;
}
}
#endif
#ifdef ENC1_SIGNAL
//! Encoder 1 interrupt handler
SIGNAL(ENC1_SIGNAL)
{
// encoder has generated a pulse
// check the relative phase of the input channels
// and update position accordingly
if( ((inb(ENC1_PHASEA_PORTIN) & (1<<ENC1_PHASEA_PIN)) == 0) ^
((inb(ENC1_PHASEB_PORTIN) & (1<<ENC1_PHASEB_PIN)) == 0) )
{
EncoderState[1].position++;
}
else
{
EncoderState[1].position--;
}
}
#endif
#ifdef ENC2_SIGNAL
//! Encoder 2 interrupt handler
SIGNAL(ENC2_SIGNAL)
{
// encoder has generated a pulse
// check the relative phase of the input channels
// and update position accordingly
if( ((inb(ENC2_PHASEA_PORTIN) & (1<<ENC2_PHASEA_PIN)) == 0) ^
((inb(ENC2_PHASEB_PORTIN) & (1<<ENC2_PHASEB_PIN)) == 0) )
{
EncoderState[2].position++;
}
else
{
EncoderState[2].position--;
}
}
#endif
#ifdef ENC3_SIGNAL
//! Encoder 3 interrupt handler
SIGNAL(ENC3_SIGNAL)
{
// encoder has generated a pulse
// check the relative phase of the input channels
// and update position accordingly
if( ((inb(ENC3_PHASEA_PORTIN) & (1<<ENC3_PHASEA_PIN)) == 0) ^
((inb(ENC3_PHASEB_PORTIN) & (1<<ENC3_PHASEB_PIN)) == 0) )
{
EncoderState[3].position++;
}
else
{
EncoderState[3].position--;
}
}
#endif

View File

@ -1,119 +0,0 @@
/*! \file encoder.h \brief Quadrature Encoder reader/driver. */
//*****************************************************************************
//
// File Name : 'encoder.h'
// Title : Quadrature Encoder reader/driver
// Author : Pascal Stang - Copyright (C) 2003-2004
// Created : 2003.01.26
// Revised : 2004.06.25
// Version : 0.3
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Description : This library allows easy interfacing of quadrature encoders
// to the Atmel AVR-series processors.
//
// Quadrature encoders have two digital outputs usually called PhaseA and
// PhaseB. When the encoder rotates, PhaseA and PhaseB produce square wave
// pulses where each pulse represents a fraction of a turn of the encoder
// shaft. Encoders are rated for a certain number of pulses (or counts) per
// complete revolution of the shaft. Common counts/revolution specs are 50,
// 100,128,200,250,256,500,etc. By counting the number of pulses output on
// one of the phases starting from time0, you can calculate the total
// rotational distance the encoder has traveled.
//
// Often, however, we want current position not just total distance traveled.
// For this it is necessary to know not only how far the encoder has traveled,
// but also which direction it was going at each step of the way. To do this
// we need to use both outputs (or phases) of the quadrature encoder.
//
// The pulses from PhaseA and PhaseB on quadrature encoders are always aligned
// 90 degrees out-of-phase (otherwise said: 1/4 wavelength apart). This
// special phase relationship lets us extract both the distance and direction
// the encoder has rotated from the outputs.
//
// To do this, consider Phase A to be the distance counter. On each rising
// edge of PhaseA we will count 1 "tic" of distance, but we need to know the
// direction. Look at the quadrature waveform plot below. Notice that when
// we travel forward in time (left->right), PhaseB is always low (logic 0) at
// the rising edge of PhaseA. When we travel backwards in time (right->left),
// PhaseB is always high (logic 1) at the rising edge of PhaseA. Note that
// traveling forward or backwards in time is the same thing as rotating
// forwards or bardwards. Thus, if PhaseA is our counter, PhaseB indicates
// direction.
//
// Here is an example waveform from a quadrature encoder:
/*
// /---\ /---\ /---\ /---\ /---\ /---\
// Phase A: | | | | | | | | | | | |
// ---/ \---/ \---/ \---/ \---/ \---/ \-
// -\ /---\ /---\ /---\ /---\ /---\ /---
// Phase B: | | | | | | | | | | | |
// \---/ \---/ \---/ \---/ \---/ \---/
// Time: <--------------------------------------------------->
// Rotate FWD: >---------------------------------------------->
// Rotate REV: <----------------------------------------------<
*/
// To keep track of the encoder position in software, we connect PhaseA to an
// external processor interrupt line, and PhaseB to any I/O pin. We set up
// the external interrupt to trigger whenever PhaseA produces a rising edge.
// When a rising edge is detected, our interrupt handler function is executed.
// Inside the handler function, we quickly check the PhaseB line to see if it
// is high or low. If it is high, we increment the encoder's position
// counter, otherwise we decrement it. The encoder position counter can be
// read at any time to find out the current position.
//
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef ENCODER_H
#define ENCODER_H
#include "global.h"
// include encoder configuration file
#include "encoderconf.h"
// constants/macros/typdefs
// defines for processor compatibility
// chose proper Interrupt Mask (IMSK)
#ifdef EIMSK
#define IMSK EIMSK // for processors mega128, mega64
#else
#define IMSK GIMSK // for other processors 90s8515, mega163, etc
#endif
//! Encoder state structure
// stores the position and other information from each encoder
typedef struct struct_EncoderState
{
s32 position; ///< position
// s32 velocity; ///< velocity
} EncoderStateType;
// functions
//! encoderInit() initializes hardware and encoder position readings
// Run this init routine once before using any other encoder function.
void encoderInit(void);
//! encoderOff() disables hardware and stops encoder position updates
void encoderOff(void);
//! encoderGetPosition() reads the current position of the encoder
s32 encoderGetPosition(u08 encoderNum);
//! encoderSetPosition() sets the current position of the encoder
void encoderSetPosition(u08 encoderNum, s32 position);
#endif

View File

@ -1,182 +0,0 @@
/*! \file extint.c \brief External-Interrupt function library. */
//*****************************************************************************
//
// File Name : 'extint.c'
// Title : External-Interrupt function library
// Author : Pascal Stang - Copyright (C) 2002-2004
// Created : 5/10/2002
// Revised : 11/16/2004
// Version : 1.0
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Notes: This library provides convenient standardized configuration and
// access to external interrupts. The library is designed to make
// it possible to write code that uses external interrupts without
// digging into the processor datasheets to find register names and
// bit-defines. The library also strives to allow code which uses
// external interrupts to more easily cross-compile between different
// microcontrollers.
//
// NOTE: Using this library has certain advantages, but also adds
// overhead and latency to interrupt servicing. If the smallest
// code size or fastest possible latency is needed, do NOT use this
// library; link your interrupts directly.
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "extint.h"
// Global variables
typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr ExtIntFunc[EXTINT_NUM_INTERRUPTS];
// functions
//! initializes extint library
void extintInit(void)
{
u08 intNum;
// detach all user functions from interrupts
for(intNum=0; intNum<EXTINT_NUM_INTERRUPTS; intNum++)
extintDetach(intNum);
}
//! Configure external interrupt trigger
// NOTE: this function is not complete!!!
void extintConfigure(u08 interruptNum, u08 configuration)
{
if(interruptNum == EXTINT0)
{
MCUCR &= ~((1<<ISC01) | (1<<ISC00));
MCUCR |= configuration;
}
#ifdef SIG_INTERRUPT1
else if(interruptNum == EXTINT1)
{
MCUCR &= ~((1<<ISC11) | (1<<ISC10));
MCUCR |= configuration<<2;
}
#endif
#ifdef SIG_INTERRUPT2
else if(interruptNum == EXTINT2)
{
if(configuration == EXTINT_EDGE_RISING)
sbi(MCUCSR, ISC2);
else
cbi(MCUCSR, ISC2);
}
#endif
// need to handle a lot more cases
// and differences between processors.
// looking for clean way to do it...
}
//! Attach a user function to an external interrupt
void extintAttach(u08 interruptNum, void (*userHandler)(void) )
{
// make sure the interrupt number is within bounds
if(interruptNum < EXTINT_NUM_INTERRUPTS)
{
// set the interrupt function to run
// the supplied user's function
ExtIntFunc[interruptNum] = userHandler;
}
}
//! Detach a user function from an external interrupt
void extintDetach(u08 interruptNum)
{
// make sure the interrupt number is within bounds
if(interruptNum < EXTINT_NUM_INTERRUPTS)
{
// set the interrupt function to run
// the supplied user's function
ExtIntFunc[interruptNum] = 0;
}
}
//! Interrupt handler for INT0
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT0)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT0])
ExtIntFunc[EXTINT0]();
}
#ifdef SIG_INTERRUPT1
//! Interrupt handler for INT1
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT1)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT1])
ExtIntFunc[EXTINT1]();
}
#endif
#ifdef SIG_INTERRUPT2
//! Interrupt handler for INT2
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT2)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT2])
ExtIntFunc[EXTINT2]();
}
#endif
#ifdef SIG_INTERRUPT3
//! Interrupt handler for INT3
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT3)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT3])
ExtIntFunc[EXTINT3]();
}
#endif
#ifdef SIG_INTERRUPT4
//! Interrupt handler for INT4
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT4)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT4])
ExtIntFunc[EXTINT4]();
}
#endif
#ifdef SIG_INTERRUPT5
//! Interrupt handler for INT5
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT5)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT5])
ExtIntFunc[EXTINT5]();
}
#endif
#ifdef SIG_INTERRUPT6
//! Interrupt handler for INT6
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT6)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT6])
ExtIntFunc[EXTINT6]();
}
#endif
#ifdef SIG_INTERRUPT7
//! Interrupt handler for INT7
EXTINT_INTERRUPT_HANDLER(SIG_INTERRUPT7)
{
// if a user function is defined, execute it
if(ExtIntFunc[EXTINT7])
ExtIntFunc[EXTINT7]();
}
#endif

View File

@ -1,104 +0,0 @@
/*! \file extint.h \brief External-Interrupt function library. */
//*****************************************************************************
//
// File Name : 'extint.h'
// Title : External-Interrupt function library
// Author : Pascal Stang - Copyright (C) 2002-2004
// Created : 5/10/2002
// Revised : 11/16/2004
// Version : 1.0
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Notes: This library provides convenient standardized configuration and
// access to external interrupts. The library is designed to make
// it possible to write code that uses external interrupts without
// digging into the processor datasheets to find register names and
// bit-defines. The library also strives to allow code which uses
// external interrupts to more easily cross-compile between different
// microcontrollers.
//
// NOTE: Using this library has certain advantages, but also adds
// overhead and latency to interrupt servicing. If the smallest
// code size or fastest possible latency is needed, do NOT use this
// library; link your interrupts directly.
//
//*****************************************************************************
#ifndef EXTINT_H
#define EXTINT_H
#include "global.h"
// constants/macros/typdefs
// interrupt macros for attaching user functions to external interrupts
// use these with extintAttach( intNum, function )
#define EXTINT0 0x00 ///< External Interrupt 0
#define EXTINT1 0x01 ///< External Interrupt 1
#define EXTINT2 0x02 ///< External Interrupt 2
#define EXTINT3 0x03 ///< External Interrupt 3
#define EXTINT4 0x04 ///< External Interrupt 4
#define EXTINT5 0x05 ///< External Interrupt 5
#define EXTINT6 0x06 ///< External Interrupt 6
#define EXTINT7 0x07 ///< External Interrupt 7
#define EXTINT_LEVEL_LOW 0x00 ///< Trigger on low level
#define EXTINT_EDGE_ANY 0x01 ///< Trigger on any edge
#define EXTINT_EDGE_FALLING 0x02 ///< Trigger on falling edge
#define EXTINT_EDGE_RISING 0x03 ///< Trigger on rising edge
// type of interrupt handler to use
// *do not change unless you know what you're doing
// Value may be SIGNAL or INTERRUPT
#ifndef EXTINT_INTERRUPT_HANDLER
#define EXTINT_INTERRUPT_HANDLER SIGNAL
#endif
// processor-adaptive defines
// mainstream AVR processors generally have 1,2,3, or 8 external interrupts
// (if someone has a better idea of how to manage this, let me know)
#ifdef SIG_INTERRUPT7
#define EXTINT_NUM_INTERRUPTS 8
#else
#ifdef SIG_INTERRUPT2
#define EXTINT_NUM_INTERRUPTS 3
#else
#ifdef SIG_INTERRUPT1
#define EXTINT_NUM_INTERRUPTS 2
#else
#define EXTINT_NUM_INTERRUPTS 1
#endif
#endif
#endif
// functions
//! initializes extint library
void extintInit(void);
//! Configure external interrupt trigger
void extintConfigure(u08 interruptNum, u08 configuration);
// extintAttach and extintDetach commands
// These functions allow the attachment (or detachment) of any user
// function to an external interrupt. "Attaching" one of your own
// functions to an interrupt means that it will be called whenever
// that interrupt is triggered. Example usage:
//
// extintAttach(EXTINT0, myInterruptHandler);
// extintDetach(EXTINT0);
//
// extintAttach causes the myInterruptHandler() to be attached, and therefore
// execute, whenever the corresponding interrupt occurs. extintDetach removes
// the association and executes no user function when the interrupt occurs.
// myInterruptFunction must be defined with no return value and no arguments:
//
// void myInterruptHandler(void) { ... }
//! Attach a user function to an external interrupt
void extintAttach(u08 interruptNum, void (*userHandler)(void) );
//! Detach a user function from an external interrupt
void extintDetach(u08 interruptNum);
#endif

View File

@ -1,364 +0,0 @@
/*! \file fat.c \brief FAT16/32 file system driver. */
//*****************************************************************************
//
// File Name : 'fat.c'
// Title : FAT16/32 file system driver
// Author : Pascal Stang
// Date : 11/07/2000
// Revised : 12/12/2000
// Version : 0.3
// Target MCU : ATmega103 (should work for Atmel AVR Series)
// Editor Tabs : 4
//
// This code is based in part on work done by Jesper Hansen for his
// YAMPP MP3 player project.
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <string.h>
#include "ata.h"
#include "rprintf.h"
#include "fat.h"
#include "fatconf.h"
// globals
unsigned char *SectorBuffer = (unsigned char *) SECTOR_BUFFER1_ADDR;
unsigned char *LongNameBuffer = (unsigned char *) LONGNAME_BUFFER_ADDR;
unsigned char *DirNameBuffer = (unsigned char *) DIRNAME_BUFFER_ADDR;
struct partrecord PartInfo;
unsigned char Fat32Enabled;
unsigned long FirstDataSector;
unsigned int BytesPerSector;
unsigned int SectorsPerCluster;
unsigned long FirstFATSector;
unsigned long FirstDirSector;
unsigned long FileSize;
unsigned long FatInCache = 0;
/*************************************************************************/
/*************************************************************************/
unsigned long fatClustToSect(unsigned long clust)
{
return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
unsigned int fatClusterSize(void)
{
// return the number of sectors in a disk cluster
return SectorsPerCluster;
}
unsigned char fatInit( unsigned char device)
{
//struct partrecord *pr;
struct bpb710 *bpb;
// read partition table
// TODO.... error checking
ataReadSectors(DRIVE0, 0, 1, SectorBuffer);
// map first partition record
// save partition information to global PartInfo
PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);
// PartInfo = *pr;
// Read the Partition BootSector
// **first sector of partition in PartInfo.prStartLBA
ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
// setup global disk constants
FirstDataSector = PartInfo.prStartLBA;
if(bpb->bpbFATsecs)
{
// bpbFATsecs is non-zero and is therefore valid
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
}
else
{
// bpbFATsecs is zero, real value is in bpbBigFATsecs
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
}
SectorsPerCluster = bpb->bpbSecPerClust;
BytesPerSector = bpb->bpbBytesPerSec;
FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
switch (PartInfo.prPartType)
{
case PART_TYPE_DOSFAT16:
case PART_TYPE_FAT16:
case PART_TYPE_FAT16LBA:
// first directory cluster is 2 by default (clusters range 2->big)
FirstDirSector = CLUST_FIRST;
// push data sector pointer to end of root directory area
//FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
Fat32Enabled = FALSE;
break;
case PART_TYPE_FAT32LBA:
case PART_TYPE_FAT32:
// bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's
FirstDirSector = bpb->bpbRootClust;
// push data sector pointer to end of root directory area
// need this? FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
Fat32Enabled = TRUE;
break;
default:
rprintfProgStrM("Found: No Partition!\r\n");
//return 1;
break;
}
#ifdef DEBUG_FAT
switch (PartInfo.prPartType)
{
case PART_TYPE_DOSFAT16:
rprintfProgStrM("Found: DOSFAT 16\r\n");
break;
case PART_TYPE_FAT16:
rprintfProgStrM("Found: FAT16\r\n");
break;
case PART_TYPE_FAT16LBA:
rprintfProgStrM("Found: FAT16 LBA\r\n");
break;
case PART_TYPE_FAT32LBA:
rprintfProgStrM("Found: FAT32 LBA\r\n");
break;
case PART_TYPE_FAT32:
rprintfProgStrM("Found: FAT32\r\n");
//return 1;
break;
default:
rprintfProgStrM("Found: No Partition!\r\n");
//return 1;
break;
}
rprintfProgStrM("First sector : "); rprintfu32(PartInfo.prStartLBA); rprintfCRLF();
rprintfProgStrM("Size : "); rprintfu32(PartInfo.prSize); rprintfCRLF();
rprintfProgStrM("bytes/sector : "); rprintfu16(bpb->bpbBytesPerSec); rprintfCRLF();
rprintfProgStrM("sectors/cluster : "); rprintfu08(bpb->bpbSecPerClust); rprintfCRLF();
rprintfProgStrM("reserved sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF();
rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF();
rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF();
rprintfProgStrM("Number of Fats : "); rprintfu08(bpb->bpbFATs); rprintfCRLF();
rprintfProgStrM("First Fat Sector: "); rprintfu32(FirstFATSector); rprintfCRLF();
rprintfProgStrM("First Data Sect : "); rprintfu32(FirstDataSector); rprintfCRLF();
rprintfProgStrM("First Dir Clust : "); rprintfu32(FirstDirSector); rprintfCRLF();
#endif
return 0;
}
//////////////////////////////////////////////////////////////
unsigned int baseentry = 0;
unsigned int entrycount = 0;
unsigned long fatGetDirEntry(unsigned int entry, unsigned int count)
{
unsigned long sector;
struct direntry *de = 0; // avoid compiler warning by initializing
struct winentry *we;
unsigned int hasBuffer;
unsigned int b;
int i,index;
char *p;
if(count == 0)
{
entrycount = 0;
DirNameBuffer = 0;
}
// read dir data
sector = fatClustToSect(FirstDirSector);
hasBuffer = 0;
index = 16; // crank it up
do
{
if(index == 16) // time for next sector ?
{
ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
de = (struct direntry *) SectorBuffer;
index = 0;
}
if(*de->deName != 0xE5)
{
// if not a deleted entry
if(de->deAttributes == ATTR_LONG_FILENAME)
{
// we have a long name entry
we = (struct winentry *) de;
b = 13 *( (we->weCnt-1) & 0x0f); // index into string
p = &LongNameBuffer[b];
for (i=0;i<5;i++) *p++ = we->wePart1[i*2]; // copy first part
for (i=0;i<6;i++) *p++ = we->wePart2[i*2]; // second part
for (i=0;i<2;i++) *p++ = we->wePart3[i*2]; // and third part
if (we->weCnt & 0x40) *p = 0; // in case dirnamelength is multiple of 13
if ((we->weCnt & 0x0f) == 1) hasBuffer = 1; // mark that we have a long entry
}
else
{
// we have a short name entry
// check if this is the end of a multi-part long name entry
if(hasBuffer)
{
// a long entry name has been collected
// is it a directory ?
if(de->deAttributes == ATTR_DIRECTORY)
{
unsigned long save = FirstDirSector;
unsigned int save2 = baseentry;
unsigned long rval;
strcpy(DirNameBuffer,LongNameBuffer);
strcat(DirNameBuffer,"/");
// rprintfStr(LongNameBuffer); rprintfProgStrM("/"); //EOL();
// call recursively
FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
rval = fatGetDirEntry(entry,1);
FirstDirSector = save;
baseentry = save2;
if (rval)
return rval;
else
{
// reload original sector
ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer);
entrycount--; // decrement entry counter
*DirNameBuffer = 0;
}
}
else // normal file entry
if(entrycount == entry)
break;
hasBuffer = 0; // clear buffer
entrycount++; // increment entry counter
}
// else ignore short_name_only entries
}
}
de++;
index++;
} while (*de->deName || index == 16); // 0 in de->deName[0] if no more entries
if (hasBuffer == 0) // end of entries
return 0;
FileSize = de->deFileSize;
return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
// return the size of the last directory entry
unsigned long fatGetFilesize(void)
{
return FileSize;
}
// return the long name of the last directory entry
char* fatGetFilename(void)
{
return LongNameBuffer;
}
// return the directory of the last directory entry
char* fatGetDirname(void)
{
return DirNameBuffer;
}
// load a clusterfull of data
void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
{
register unsigned char i;
// read cluster
//while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);
for(i=0; i<SectorsPerCluster; i++)
{
// ataReadSectors( DRIVE0, clust2sect(cluster)+i, 1, buffer+(i<<9) );
// temporary fix for wierd misaligned cluster problem
// (only when using FAT16?)
ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i<<9) );
}
}
// find next cluster in the FAT chain
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster;
unsigned long fatMask;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
// get fat offset in bytes
if(Fat32Enabled)
{
// four FAT bytes (32 bits) for every cluster
fatOffset = cluster << 2;
// set the FAT bit mask
fatMask = FAT32_MASK;
}
else
{
// two FAT bytes (16 bits) for every cluster
fatOffset = cluster << 1;
// set the FAT bit mask
fatMask = FAT16_MASK;
}
// calculate the FAT sector that we're interested in
sector = FirstFATSector + (fatOffset / BytesPerSector);
// calculate offset of the our entry within that FAT sector
offset = fatOffset % BytesPerSector;
// if we don't already have this FAT chunk loaded, go get it
if (sector != FatInCache)
{
// read sector of FAT table
while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
FatInCache = sector;
}
// read the nextCluster value
nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
// check to see if we're at the end of the chain
if (nextCluster == (CLUST_EOFE & fatMask))
nextCluster = 0;
#ifdef DEBUG_FAT
rprintfProgStrM(">");
rprintfu32(nextCluster);
rprintfCRLF();
#endif
return nextCluster;
}

View File

@ -1,375 +0,0 @@
/*! \file fat.h \brief FAT16/32 file system driver. */
//*****************************************************************************
//
// File Name : 'fat.h'
// Title : FAT16/32 file system driver
// Author : Pascal Stang
// Date : 11/07/2000
// Revised : 12/12/2000
// Version : 0.3
// Target MCU : ATmega103 (should work for Atmel AVR Series)
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef FAT_H
#define FAT_H
#include "global.h"
// Some useful cluster numbers
#define MSDOSFSROOT 0 // cluster 0 means the root dir
#define CLUST_FREE 0 // cluster 0 also means a free cluster
#define MSDOSFSFREE CLUST_FREE
#define CLUST_FIRST 2 // first legal cluster number
#define CLUST_RSRVD 0xfffffff6 // reserved cluster range
#define CLUST_BAD 0xfffffff7 // a cluster with a defect
#define CLUST_EOFS 0xfffffff8 // start of eof cluster range
#define CLUST_EOFE 0xffffffff // end of eof cluster range
#define FAT12_MASK 0x00000fff // mask for 12 bit cluster numbers
#define FAT16_MASK 0x0000ffff // mask for 16 bit cluster numbers
#define FAT32_MASK 0x0fffffff // mask for FAT32 cluster numbers
// Partition Type used in the partition record
#define PART_TYPE_UNKNOWN 0x00
#define PART_TYPE_FAT12 0x01
#define PART_TYPE_XENIX 0x02
#define PART_TYPE_DOSFAT16 0x04
#define PART_TYPE_EXTDOS 0x05
#define PART_TYPE_FAT16 0x06
#define PART_TYPE_NTFS 0x07
#define PART_TYPE_FAT32 0x0B
#define PART_TYPE_FAT32LBA 0x0C
#define PART_TYPE_FAT16LBA 0x0E
#define PART_TYPE_EXTDOSLBA 0x0F
#define PART_TYPE_ONTRACK 0x33
#define PART_TYPE_NOVELL 0x40
#define PART_TYPE_PCIX 0x4B
#define PART_TYPE_PHOENIXSAVE 0xA0
#define PART_TYPE_CPM 0xDB
#define PART_TYPE_DBFS 0xE0
#define PART_TYPE_BBT 0xFF
struct partrecord // length 16 bytes
{
BYTE prIsActive; // 0x80 indicates active partition
BYTE prStartHead; // starting head for partition
WORD prStartCylSect; // starting cylinder and sector
BYTE prPartType; // partition type (see above)
BYTE prEndHead; // ending head for this partition
WORD prEndCylSect; // ending cylinder and sector
DWORD prStartLBA; // first LBA sector for this partition
DWORD prSize; // size of this partition (bytes or sectors ?)
};
struct partsector
{
CHAR psPartCode[512-64-2]; // pad so struct is 512b
BYTE psPart[64]; // four partition records (64 bytes)
BYTE psBootSectSig0; // two signature bytes (2 bytes)
BYTE psBootSectSig1;
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
// Format of a boot sector. This is the first sector on a DOS floppy disk
// or the first sector of a partition on a hard disk. But, it is not the
// first sector of a partitioned hard disk.
struct bootsector33 {
BYTE bsJump[3]; // jump inst E9xxxx or EBxx90
CHAR bsOemName[8]; // OEM name and version
CHAR bsBPB[19]; // BIOS parameter block
CHAR bsDriveNumber; // drive number (0x80)
CHAR bsBootCode[479]; // pad so struct is 512b
BYTE bsBootSectSig0; // boot sector signature byte 0x55
BYTE bsBootSectSig1; // boot sector signature byte 0xAA
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
struct extboot {
CHAR exDriveNumber; // drive number (0x80)
CHAR exReserved1; // reserved
CHAR exBootSignature; // ext. boot signature (0x29)
#define EXBOOTSIG 0x29
CHAR exVolumeID[4]; // volume ID number
CHAR exVolumeLabel[11]; // volume label
CHAR exFileSysType[8]; // fs type (FAT12 or FAT16)
};
struct bootsector50 {
BYTE bsJump[3]; // jump inst E9xxxx or EBxx90
CHAR bsOemName[8]; // OEM name and version
CHAR bsBPB[25]; // BIOS parameter block
CHAR bsExt[26]; // Bootsector Extension
CHAR bsBootCode[448]; // pad so structure is 512b
BYTE bsBootSectSig0; // boot sector signature byte 0x55
BYTE bsBootSectSig1; // boot sector signature byte 0xAA
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
struct bootsector710 {
BYTE bsJump[3]; // jump inst E9xxxx or EBxx90
CHAR bsOEMName[8]; // OEM name and version
CHAR bsBPB[53]; // BIOS parameter block
CHAR bsExt[26]; // Bootsector Extension
CHAR bsBootCode[418]; // pad so structure is 512b
BYTE bsBootSectSig2; // 2 & 3 are only defined for FAT32?
BYTE bsBootSectSig3;
BYTE bsBootSectSig0; // boot sector signature byte 0x55
BYTE bsBootSectSig1; // boot sector signature byte 0xAA
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
#define BOOTSIG2 0
#define BOOTSIG3 0
};
/***************************************************************/
/***************************************************************/
// BIOS Parameter Block (BPB) for DOS 3.3
struct bpb33 {
WORD bpbBytesPerSec; // bytes per sector
BYTE bpbSecPerClust; // sectors per cluster
WORD bpbResSectors; // number of reserved sectors
BYTE bpbFATs; // number of FATs
WORD bpbRootDirEnts; // number of root directory entries
WORD bpbSectors; // total number of sectors
BYTE bpbMedia; // media descriptor
WORD bpbFATsecs; // number of sectors per FAT
WORD bpbSecPerTrack; // sectors per track
WORD bpbHeads; // number of heads
WORD bpbHiddenSecs; // number of hidden sectors
};
// BPB for DOS 5.0
// The difference is bpbHiddenSecs is a short for DOS 3.3,
// and bpbHugeSectors is not present in the DOS 3.3 bpb.
struct bpb50 {
WORD bpbBytesPerSec; // bytes per sector
BYTE bpbSecPerClust; // sectors per cluster
WORD bpbResSectors; // number of reserved sectors
BYTE bpbFATs; // number of FATs
WORD bpbRootDirEnts; // number of root directory entries
WORD bpbSectors; // total number of sectors
BYTE bpbMedia; // media descriptor
WORD bpbFATsecs; // number of sectors per FAT
WORD bpbSecPerTrack; // sectors per track
WORD bpbHeads; // number of heads
DWORD bpbHiddenSecs; // # of hidden sectors
// 3.3 compat ends here
DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0
};
// BPB for DOS 7.10 (FAT32)
// This one has a few extensions to bpb50.
struct bpb710 {
WORD bpbBytesPerSec; // bytes per sector
BYTE bpbSecPerClust; // sectors per cluster
WORD bpbResSectors; // number of reserved sectors
BYTE bpbFATs; // number of FATs
WORD bpbRootDirEnts; // number of root directory entries
WORD bpbSectors; // total number of sectors
BYTE bpbMedia; // media descriptor
WORD bpbFATsecs; // number of sectors per FAT
WORD bpbSecPerTrack; // sectors per track
WORD bpbHeads; // number of heads
DWORD bpbHiddenSecs; // # of hidden sectors
// 3.3 compat ends here
DWORD bpbHugeSectors; // # of sectors if bpbSectors == 0
// 5.0 compat ends here
DWORD bpbBigFATsecs;// like bpbFATsecs for FAT32
WORD bpbExtFlags; // extended flags:
#define FATNUM 0xf // mask for numbering active FAT
#define FATMIRROR 0x80 // FAT is mirrored (like it always was)
WORD bpbFSVers; // filesystem version
#define FSVERS 0 // currently only 0 is understood
DWORD bpbRootClust; // start cluster for root directory
WORD bpbFSInfo; // filesystem info structure sector
WORD bpbBackup; // backup boot sector
// There is a 12 byte filler here, but we ignore it
};
// ***************************************************************
// * byte versions of the above structs *
// ***************************************************************
// BIOS Parameter Block (BPB) for DOS 3.3
struct byte_bpb33 {
CHAR bpbBytesPerSec[2]; // bytes per sector
CHAR bpbSecPerClust; // sectors per cluster
CHAR bpbResSectors[2]; // number of reserved sectors
CHAR bpbFATs; // number of FATs
CHAR bpbRootDirEnts[2]; // number of root directory entries
CHAR bpbSectors[2]; // total number of sectors
CHAR bpbMedia; // media descriptor
CHAR bpbFATsecs[2]; // number of sectors per FAT
CHAR bpbSecPerTrack[2]; // sectors per track
CHAR bpbHeads[2]; // number of heads
CHAR bpbHiddenSecs[2]; // number of hidden sectors
};
// BPB for DOS 5.0
// The difference is bpbHiddenSecs is a short for DOS 3.3,
// and bpbHugeSectors is not in the 3.3 bpb.
struct byte_bpb50 {
CHAR bpbBytesPerSec[2]; // bytes per sector
CHAR bpbSecPerClust; // sectors per cluster
CHAR bpbResSectors[2]; // number of reserved sectors
CHAR bpbFATs; // number of FATs
CHAR bpbRootDirEnts[2]; // number of root directory entries
CHAR bpbSectors[2]; // total number of sectors
CHAR bpbMedia; // media descriptor
CHAR bpbFATsecs[2]; // number of sectors per FAT
CHAR bpbSecPerTrack[2]; // sectors per track
CHAR bpbHeads[2]; // number of heads
CHAR bpbHiddenSecs[4]; // number of hidden sectors
CHAR bpbHugeSectors[4]; // # of sectors if bpbSectors == 0
};
// BPB for DOS 7.10 (FAT32).
// This one has a few extensions to bpb50.
struct byte_bpb710 {
BYTE bpbBytesPerSec[2]; // bytes per sector
BYTE bpbSecPerClust; // sectors per cluster
BYTE bpbResSectors[2]; // number of reserved sectors
BYTE bpbFATs; // number of FATs
BYTE bpbRootDirEnts[2]; // number of root directory entries
BYTE bpbSectors[2]; // total number of sectors
BYTE bpbMedia; // media descriptor
BYTE bpbFATsecs[2]; // number of sectors per FAT
BYTE bpbSecPerTrack[2]; // sectors per track
BYTE bpbHeads[2]; // number of heads
BYTE bpbHiddenSecs[4]; // # of hidden sectors
BYTE bpbHugeSectors[4]; // # of sectors if bpbSectors == 0
BYTE bpbBigFATsecs[4]; // like bpbFATsecs for FAT32
BYTE bpbExtFlags[2]; // extended flags:
BYTE bpbFSVers[2]; // filesystem version
BYTE bpbRootClust[4]; // start cluster for root directory
BYTE bpbFSInfo[2]; // filesystem info structure sector
BYTE bpbBackup[2]; // backup boot sector
// There is a 12 byte filler here, but we ignore it
};
// FAT32 FSInfo block.
struct fsinfo {
BYTE fsisig1[4];
BYTE fsifill1[480];
BYTE fsisig2[4];
BYTE fsinfree[4];
BYTE fsinxtfree[4];
BYTE fsifill2[12];
BYTE fsisig3[4];
BYTE fsifill3[508];
BYTE fsisig4[4];
};
/***************************************************************/
/***************************************************************/
// Structure of a dos directory entry.
struct direntry {
BYTE deName[8]; // filename, blank filled
#define SLOT_EMPTY 0x00 // slot has never been used
#define SLOT_E5 0x05 // the real value is 0xe5
#define SLOT_DELETED 0xe5 // file in this slot deleted
BYTE deExtension[3]; // extension, blank filled
BYTE deAttributes; // file attributes
#define ATTR_NORMAL 0x00 // normal file
#define ATTR_READONLY 0x01 // file is readonly
#define ATTR_HIDDEN 0x02 // file is hidden
#define ATTR_SYSTEM 0x04 // file is a system file
#define ATTR_VOLUME 0x08 // entry is a volume label
#define ATTR_LONG_FILENAME 0x0f // this is a long filename entry
#define ATTR_DIRECTORY 0x10 // entry is a directory name
#define ATTR_ARCHIVE 0x20 // file is new or modified
BYTE deLowerCase; // NT VFAT lower case flags
#define LCASE_BASE 0x08 // filename base in lower case
#define LCASE_EXT 0x10 // filename extension in lower case
BYTE deCHundredth; // hundredth of seconds in CTime
BYTE deCTime[2]; // create time
BYTE deCDate[2]; // create date
BYTE deADate[2]; // access date
WORD deHighClust; // high bytes of cluster number
BYTE deMTime[2]; // last update time
BYTE deMDate[2]; // last update date
WORD deStartCluster; // starting cluster of file
DWORD deFileSize; // size of file in bytes
};
// number of directory entries in one sector
#define DIRENTRIES_PER_SECTOR 0x10
// Structure of a Win95 long name directory entry
struct winentry {
BYTE weCnt;
#define WIN_LAST 0x40
#define WIN_CNT 0x3f
BYTE wePart1[10];
BYTE weAttributes;
#define ATTR_WIN95 0x0f
BYTE weReserved1;
BYTE weChksum;
BYTE wePart2[12];
WORD weReserved2;
BYTE wePart3[4];
};
#define WIN_CHARS 13 // Number of chars per winentry
// Maximum filename length in Win95
// Note: Must be < sizeof(dirent.d_name)
#define WIN_MAXLEN 255
// This is the format of the contents of the deTime field in the direntry
// structure.
// We don't use bitfields because we don't know how compilers for
// arbitrary machines will lay them out.
#define DT_2SECONDS_MASK 0x1F // seconds divided by 2
#define DT_2SECONDS_SHIFT 0
#define DT_MINUTES_MASK 0x7E0 // minutes
#define DT_MINUTES_SHIFT 5
#define DT_HOURS_MASK 0xF800 // hours
#define DT_HOURS_SHIFT 11
// This is the format of the contents of the deDate field in the direntry
// structure.
#define DD_DAY_MASK 0x1F // day of month
#define DD_DAY_SHIFT 0
#define DD_MONTH_MASK 0x1E0 // month
#define DD_MONTH_SHIFT 5
#define DD_YEAR_MASK 0xFE00 // year - 1980
#define DD_YEAR_SHIFT 9
// Prototypes
unsigned char fatInit( unsigned char device);
unsigned int fatClusterSize(void);
unsigned long fatGetDirEntry(unsigned int entry, unsigned int count);
unsigned long fatGetFilesize(void);
char* fatGetFilename(void);
char* fatGetDirname(void);
void fatLoadCluster(unsigned long cluster, unsigned char *buffer);
unsigned long fatNextCluster(unsigned long cluster);
#endif

View File

@ -1,85 +0,0 @@
/*! \file fixedpt.c \brief Fixed-point math function library. */
//*****************************************************************************
//
// File Name : 'fixedpt.c'
// Title : Fixed-point math function library
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.01.26
// Revised : 2003.02.02
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "fixedpt.h"
// Program ROM constants
// Global variables
u08 FixedPtBits;
// Functions
// fixedptInit() initializes fixed-point math function library
void fixedptInit(u08 fixedPtBits)
{
// set the number of bits to use behind the point
FixedPtBits = fixedPtBits;
}
s32 fixedptConvertFromInt(s32 int_number)
{
// convert integer to fixed-point number
return (int_number<<FixedPtBits);
}
s32 fixedptConvertToInt(s32 fp_number)
{
// convert fixed-point number to integer
// do rounding
if( fp_number & 1<<(FixedPtBits-1) )
{
// bit behind the point was a '1'
// round up to next higher integer
return (fp_number>>FixedPtBits)+1;
}
else
{
// bit behind the point was a '0'
// round down (truncate) to next lower integer
return (fp_number>>FixedPtBits);
}
}
s32 fixedptAdd(s32 a, s32 b)
{
// add a and b (a+b) with fixed-point math
return a+b;
}
s32 fixedptSubtract(s32 a, s32 b)
{
// subtract a and b (a-b) with fixed-point math
return a-b;
}
s32 fixedptMultiply(s32 a, s32 b)
{
// multiply a and b (a*b) with fixed-point math
return (a*b)>>FixedPtBits;
}
s32 fixedptDivide(s32 numer, s32 denom)
{
// divide numer by denom (numer/denom) with fixed-point math
return (numer<<FixedPtBits)/denom;
}

View File

@ -1,53 +0,0 @@
/*! \file fixedpt.h \brief Fixed-point math function library. */
//*****************************************************************************
//
// File Name : 'fixedpt.h'
// Title : Fixed-point math function library
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.01.26
// Revised : 2003.02.04
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef FIXEDPT_H
#define FIXEDPT_H
#include "global.h"
// constants/macros/typdefs
// functions
//! fixedptInit() initializes fixed-point math function library
// set the number of bits to use behind the point
void fixedptInit(u08 fixedPtBits);
//! convert integer to fixed-point number
s32 fixedptConvertFromInt(s32 int_number);
//! convert fixed-point number to integer
s32 fixedptConvertToInt(s32 fp_number);
//! add a and b (a+b) with fixed-point math
s32 fixedptAdd(s32 a, s32 b);
//! subtract a and b (a-b) with fixed-point math
s32 fixedptSubtract(s32 a, s32 b);
//! multiply a and b (a*b) with fixed-point math
s32 fixedptMultiply(s32 a, s32 b);
//! divide numer by denom (numer/denom) with fixed-point math
s32 fixedptDivide(s32 numer, s32 denom);
#endif

View File

@ -1,119 +0,0 @@
/*! \file font5x7.h \brief Graphic LCD Font (Ascii Characters). */
//*****************************************************************************
//
// File Name : 'font5x7.h'
// Title : Graphic LCD Font (Ascii Charaters)
// Author : Pascal Stang
// Date : 10/19/2001
// Revised : 10/19/2001
// Version : 0.1
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
//*****************************************************************************
#ifndef FONT5X7_H
#define FONT5X7_H
// standard ascii 5x7 font
// defines ascii characters 0x20-0x7F (32-127)
static unsigned char __attribute__ ((progmem)) Font5x7[] = {
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
0x00, 0x00, 0x5F, 0x00, 0x00,// !
0x00, 0x07, 0x00, 0x07, 0x00,// "
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
0x23, 0x13, 0x08, 0x64, 0x62,// %
0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x1C, 0x22, 0x41, 0x00,// (
0x00, 0x41, 0x22, 0x1C, 0x00,// )
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x50, 0x30, 0x00, 0x00,// ,
0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x60, 0x60, 0x00, 0x00,// .
0x20, 0x10, 0x08, 0x04, 0x02,// /
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41,// <
0x14, 0x14, 0x14, 0x14, 0x14,// =
0x41, 0x22, 0x14, 0x08, 0x00,// >
0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x32, 0x49, 0x79, 0x41, 0x3E,// @
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x7F, 0x09, 0x09, 0x01, 0x01,// F
0x3E, 0x41, 0x41, 0x51, 0x32,// G
0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x7F, 0x02, 0x04, 0x02, 0x7F,// M
0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x46, 0x49, 0x49, 0x49, 0x31,// S
0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x7F, 0x20, 0x18, 0x20, 0x7F,// W
0x63, 0x14, 0x08, 0x14, 0x63,// X
0x03, 0x04, 0x78, 0x04, 0x03,// Y
0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41,// [
0x02, 0x04, 0x08, 0x10, 0x20,// "\"
0x41, 0x41, 0x7F, 0x00, 0x00,// ]
0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x01, 0x02, 0x04, 0x00,// `
0x20, 0x54, 0x54, 0x54, 0x78,// a
0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x38, 0x44, 0x44, 0x44, 0x20,// c
0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x38, 0x54, 0x54, 0x54, 0x18,// e
0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x08, 0x14, 0x54, 0x54, 0x3C,// g
0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x20, 0x40, 0x44, 0x3D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44,// k
0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x38, 0x44, 0x44, 0x44, 0x38,// o
0x7C, 0x14, 0x14, 0x14, 0x08,// p
0x08, 0x14, 0x14, 0x18, 0x7C,// q
0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x48, 0x54, 0x54, 0x54, 0x20,// s
0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x44, 0x28, 0x10, 0x28, 0x44,// x
0x0C, 0x50, 0x50, 0x50, 0x3C,// y
0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x00, 0x08, 0x36, 0x41, 0x00,// {
0x00, 0x00, 0x7F, 0x00, 0x00,// |
0x00, 0x41, 0x36, 0x08, 0x00,// }
0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
};
#endif

View File

@ -1,31 +0,0 @@
/*! \file fontgr.h \brief Graphic LCD Font (Graphic Characters). */
//*****************************************************************************
//
// File Name : 'fontgr.h'
// Title : Graphic LCD Font (Graphic Charaters)
// Author : Pascal Stang
// Date : 10/19/2001
// Revised : 10/19/2001
// Version : 0.1
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
//*****************************************************************************
#ifndef FONTGR_H
#define FONTGR_H
#ifndef WIN32
// AVR specific includes
#include <avr/pgmspace.h>
#endif
static unsigned char __attribute__ ((progmem)) FontGr[] =
{
// format is one character per line:
// length, byte array[length]
0x0B,0x3E,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x3C,0x00,// 0. Folder Icon
0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF // 1. Solid 6x8 block
};
#endif

View File

@ -1,164 +0,0 @@
/*! \file glcd.c \brief Graphic LCD API functions. */
//*****************************************************************************
//
// File Name : 'glcd.c'
// Title : Graphic LCD API functions
// Author : Pascal Stang - Copyright (C) 2002
// Date : 5/30/2002
// Revised : 5/30/2002
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
// AVR specific includes
#include <avr/io.h>
#include <avr/pgmspace.h>
#endif
#include "glcd.h"
// include hardware support
#include "ks0108.h"
// include fonts
#include "font5x7.h"
#include "fontgr.h"
// graphic routines
// set dot
void glcdSetDot(u08 x, u08 y)
{
unsigned char temp;
glcdSetAddress(x, y/8);
temp = glcdDataRead(); // dummy read
temp = glcdDataRead(); // read back current value
glcdSetAddress(x, y/8);
glcdDataWrite(temp | (1 << (y % 8)));
glcdStartLine(0);
}
// clear dot
void glcdClearDot(u08 x, u08 y)
{
unsigned char temp;
glcdSetAddress(x, y/8);
temp = glcdDataRead(); // dummy read
temp = glcdDataRead(); // read back current value
glcdSetAddress(x, y/8);
glcdDataWrite(temp & ~(1 << (y % 8)));
glcdStartLine(0);
}
// draw line
void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2)
{
};
// draw rectangle
void glcdRectangle(u08 x, u08 y, u08 a, u08 b)
{
unsigned char j;
for (j = 0; j < a; j++) {
glcdSetDot(x, y + j);
glcdSetDot(x + b - 1, y + j);
}
for (j = 0; j < b; j++) {
glcdSetDot(x + j, y);
glcdSetDot(x + j, y + a - 1);
}
}
// draw circle
void glcdCircle(u08 xcenter, u08 ycenter, u08 radius)
{
int tswitch, y, x = 0;
unsigned char d;
d = ycenter - xcenter;
y = radius;
tswitch = 3 - 2 * radius;
while (x <= y) {
glcdSetDot(xcenter + x, ycenter + y); glcdSetDot(xcenter + x, ycenter - y);
glcdSetDot(xcenter - x, ycenter + y); glcdSetDot(xcenter - x, ycenter - y);
glcdSetDot(ycenter + y - d, ycenter + x); glcdSetDot(ycenter + y - d, ycenter - x);
glcdSetDot(ycenter - y - d, ycenter + x); glcdSetDot(ycenter - y - d, ycenter - x);
if (tswitch < 0) tswitch += (4 * x + 6);
else {
tswitch += (4 * (x - y) + 10);
y--;
}
x++;
}
}
// text routines
// write a character at the current position
void glcdWriteChar(unsigned char c)
{
u08 i = 0;
for(i=0; i<5; i++)
{
glcdDataWrite(pgm_read_byte(&Font5x7[((c - 0x20) * 5) + i]));
}
// write a spacer line
glcdDataWrite(0x00);
// unless we're at the end of the display
//if(xx == 128)
// xx = 0;
//else
// glcdWriteData(0x00);
//cbi(GLCD_Control, GLCD_CS1);
//cbi(GLCD_Control, GLCD_CS2);
glcdStartLine(0);
}
void glcdWriteCharGr(u08 grCharIdx)
{
u08 idx;
u08 grLength;
u08 grStartIdx = 0;
// get starting index of graphic bitmap
for(idx=0; idx<grCharIdx; idx++)
{
// add this graphic's length to the startIdx
// to get the startIdx of the next one
grStartIdx += pgm_read_byte(FontGr+grStartIdx);
}
grLength = pgm_read_byte(FontGr+grStartIdx);
// write the lines of the desired graphic to the display
for(idx=0; idx<grLength; idx++)
{
// write the line
glcdDataWrite(pgm_read_byte(FontGr+(grStartIdx+1)+idx));
}
}
void glcdPutStr(unsigned char *data)
{
while (*data) {
glcdWriteChar(*data);
data++;
}
}

View File

@ -1,73 +0,0 @@
/*! \file glcd.h \brief Graphic LCD API functions. */
//*****************************************************************************
//
// File Name : 'glcd.h'
// Title : Graphic LCD API functions
// Author : Pascal Stang - Copyright (C) 2002
// Date : 5/30/2002
// Revised : 5/30/2002
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef GLCD_H
#define GLCD_H
#ifndef WIN32
// AVR specific includes
#include <avr/io.h>
#endif
#include "global.h"
#define LINE1 0
#define LINE2 1
#define LINE3 2
#define LINE4 3
#define LINE5 4
#define LINE6 5
#define LINE7 6
#define LINE8 7
#define ON 1
#define OFF 0
// API-level interface commands
// ***** Public Functions *****
//! set a dot on the display (x is horiz 0:127, y is vert 0:63)
void glcdSetDot(u08 x, u08 y);
//! clear a dot on the display (x is horiz 0:127, y is vert 0:63)
void glcdClearDot(u08 x, u08 y);
//! draw line
void glcdLine(u08 x1, u08 y1, u08 x2, u08 y2);
//! draw rectangle (coords????)
void glcdRectangle(u08 x, u08 y, u08 a, u08 b);
//! draw circle of <radius> at <xcenter,ycenter>
void glcdCircle(u08 xcenter, u08 ycenter, u08 radius);
//! write a standard ascii charater (values 20-127)
// to the display at current position
void glcdWriteChar(unsigned char c);
//! write a special graphic character/icon
// to the display at current position
void glcdWriteCharGr(u08 grCharIndex);
// ***** Private Functions ***** (or depricated)
void glcdPutStr(u08 *data);
#endif

View File

@ -1,84 +0,0 @@
/*! \file gps.c \brief GPS position storage and processing library. */
//*****************************************************************************
//
// File Name : 'gps.c'
// Title : GPS position storage and processing function library
// Author : Pascal Stang - Copyright (C) 2002-2005
// Created : 2005.01.14
// Revised : 2002.07.17
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <stdlib.h>
#endif
#include "global.h"
#include "rprintf.h"
#include "gps.h"
// Global variables
GpsInfoType GpsInfo;
// Functions
void gpsInit(void)
{
}
GpsInfoType* gpsGetInfo(void)
{
return &GpsInfo;
}
void gpsInfoPrint(void)
{
rprintfProgStrM("TOW: "); rprintfFloat(8, GpsInfo.TimeOfWeek.f); rprintfCRLF();
rprintfProgStrM("WkNum: "); rprintfNum(10,4,0,' ',GpsInfo.WeekNum); rprintfCRLF();
rprintfProgStrM("UTCoffset:"); rprintfFloat(8, GpsInfo.UtcOffset.f); rprintfCRLF();
rprintfProgStrM("Num SVs: "); rprintfNum(10,4,0,' ',GpsInfo.numSVs); rprintfCRLF();
rprintfProgStrM("X_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.x.f); rprintfCRLF();
rprintfProgStrM("Y_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.y.f); rprintfCRLF();
rprintfProgStrM("Z_ECEF: "); rprintfFloat(8, GpsInfo.PosECEF.z.f); rprintfCRLF();
rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosECEF.TimeOfFix.f); rprintfCRLF();
rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosECEF.updates); rprintfCRLF();
//u08 str[20];
//rprintfProgStrM(" PosLat: "); rprintfStr(dtostrf(GpsInfo.PosLat.f, 10, 5, str));
rprintfProgStrM("PosLat: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lat.f/PI)); rprintfCRLF();
rprintfProgStrM("PosLon: "); rprintfFloat(8, 180*(GpsInfo.PosLLA.lon.f/PI)); rprintfCRLF();
rprintfProgStrM("PosAlt: "); rprintfFloat(8, GpsInfo.PosLLA.alt.f); rprintfCRLF();
rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.PosLLA.TimeOfFix.f); rprintfCRLF();
rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.PosLLA.updates); rprintfCRLF();
rprintfProgStrM("Vel East: "); rprintfFloat(8, GpsInfo.VelENU.east.f); rprintfCRLF();
rprintfProgStrM("Vel North:"); rprintfFloat(8, GpsInfo.VelENU.north.f); rprintfCRLF();
rprintfProgStrM("Vel Up: "); rprintfFloat(8, GpsInfo.VelENU.up.f); rprintfCRLF();
// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelENU.TimeOfFix.f); rprintfCRLF();
rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelENU.updates); rprintfCRLF();
rprintfProgStrM("Vel Head: "); rprintfFloat(8, GpsInfo.VelHS.heading.f); rprintfCRLF();
rprintfProgStrM("Vel Speed:"); rprintfFloat(8, GpsInfo.VelHS.speed.f); rprintfCRLF();
// rprintfProgStrM("TOF: "); rprintfFloat(8, GpsInfo.VelHS.TimeOfFix.f); rprintfCRLF();
rprintfProgStrM("Updates: "); rprintfNum(10,6,0,' ',GpsInfo.VelHS.updates); rprintfCRLF();
}

View File

@ -1,106 +0,0 @@
/*! \file gps.h \brief GPS position storage and processing library. */
//*****************************************************************************
//
// File Name : 'gps.h'
// Title : GPS position storage and processing function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 2002.08.29
// Revised : 2002.08.29
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef GPS_H
#define GPS_H
#include "global.h"
// constants/macros/typdefs
typedef union union_float_u32
{
float f;
unsigned long i;
unsigned char b[4];
} float_u32;
typedef union union_double_u64
{
double f;
unsigned long long i;
unsigned char b[8];
} double_u64;
struct PositionLLA
{
float_u32 lat;
float_u32 lon;
float_u32 alt;
float_u32 TimeOfFix;
u16 updates;
};
struct VelocityENU
{
float_u32 east;
float_u32 north;
float_u32 up;
float_u32 TimeOfFix;
u16 updates;
};
struct VelocityHS
{
float_u32 heading;
float_u32 speed;
float_u32 TimeOfFix;
u16 updates;
};
struct PositionECEF
{
float_u32 x;
float_u32 y;
float_u32 z;
float_u32 TimeOfFix;
u16 updates;
};
struct VelocityECEF
{
float_u32 x;
float_u32 y;
float_u32 z;
float_u32 TimeOfFix;
u16 updates;
};
typedef struct struct_GpsInfo
{
float_u32 TimeOfWeek;
u16 WeekNum;
float_u32 UtcOffset;
u08 numSVs;
struct PositionLLA PosLLA;
struct PositionECEF PosECEF;
struct VelocityECEF VelECEF;
struct VelocityENU VelENU;
struct VelocityHS VelHS;
} GpsInfoType;
// functions
void gpsInit(void);
GpsInfoType* gpsGetInfo(void);
void gpsInfoPrint(void);
#endif

View File

@ -1,635 +0,0 @@
/*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */
//*****************************************************************************
//
// File Name : 'i2c.c'
// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware
// Author : Pascal Stang - Copyright (C) 2002-2003
// Created : 2002.06.25
// Revised : 2003.03.02
// Version : 0.9
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : I2C (pronounced "eye-squared-see") is a two-wire bidirectional
// network designed for easy transfer of information between a wide variety
// of intelligent devices. Many of the Atmel AVR series processors have
// hardware support for transmitting and receiving using an I2C-type bus.
// In addition to the AVRs, there are thousands of other parts made by
// manufacturers like Philips, Maxim, National, TI, etc that use I2C as
// their primary means of communication and control. Common device types
// are A/D & D/A converters, temp sensors, intelligent battery monitors,
// MP3 decoder chips, EEPROM chips, multiplexing switches, etc.
//
// I2C uses only two wires (SDA and SCL) to communicate bidirectionally
// between devices. I2C is a multidrop network, meaning that you can have
// several devices on a single bus. Because I2C uses a 7-bit number to
// identify which device it wants to talk to, you cannot have more than
// 127 devices on a single bus.
//
// I2C ordinarily requires two 4.7K pull-up resistors to power (one each on
// SDA and SCL), but for small numbers of devices (maybe 1-4), it is enough
// to activate the internal pull-up resistors in the AVR processor. To do
// this, set the port pins, which correspond to the I2C pins SDA/SCL, high.
// For example, on the mega163, sbi(PORTC, 0); sbi(PORTC, 1);.
//
// For complete information about I2C, see the Philips Semiconductor
// website. They created I2C and have the largest family of devices that
// work with I2C.
//
// Note: Many manufacturers market I2C bus devices under a different or generic
// bus name like "Two-Wire Interface". This is because Philips still holds
// "I2C" as a trademark. For example, SMBus and SMBus devices are hardware
// compatible and closely related to I2C. They can be directly connected
// to an I2C bus along with other I2C devices are are generally accessed in
// the same way as I2C devices. SMBus is often found on modern motherboards
// for temp sensing and other low-level control tasks.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "i2c.h"
#include "rprintf.h" // include printf function library
#include "uart2.h"
// Standard I2C bit rates are:
// 100KHz for slow speed
// 400KHz for high speed
//#define I2C_DEBUG
// I2C state and address variables
static volatile eI2cStateType I2cState;
static u08 I2cDeviceAddrRW;
// send/transmit buffer (outgoing data)
static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
static u08 I2cSendDataIndex;
static u08 I2cSendDataLength;
// receive buffer (incoming data)
static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
static u08 I2cReceiveDataIndex;
static u08 I2cReceiveDataLength;
// function pointer to i2c receive routine
//! I2cSlaveReceive is called when this processor
// is addressed as a slave for writing
static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);
//! I2cSlaveTransmit is called when this processor
// is addressed as a slave for reading
static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
// functions
void i2cInit(void)
{
// set pull-up resistors on I2C bus pins
// TODO: should #ifdef these
sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc
sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc
sbi(PORTD, 0); // i2c SCL on ATmega128,64
sbi(PORTD, 1); // i2c SDA on ATmega128,64
// clear SlaveReceive and SlaveTransmit handler to null
i2cSlaveReceive = 0;
i2cSlaveTransmit = 0;
// set i2c bit rate to 100KHz
i2cSetBitrate(100);
// enable TWI (two-wire interface)
sbi(TWCR, TWEN);
// set state
I2cState = I2C_IDLE;
// enable TWI interrupt and slave address ACK
sbi(TWCR, TWIE);
sbi(TWCR, TWEA);
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
// enable interrupts
sei();
}
void i2cSetBitrate(u16 bitrateKHz)
{
u08 bitrate_div;
// set i2c bitrate
// SCL freq = F_CPU/(16+2*TWBR))
#ifdef TWPS0
// for processors with additional bitrate division (mega128)
// SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
// set TWPS to zero
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
#endif
// calculate bitrate division
bitrate_div = ((F_CPU/1000l)/bitrateKHz);
if(bitrate_div >= 16)
bitrate_div = (bitrate_div-16)/2;
outb(TWBR, bitrate_div);
}
void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
{
// set local device address (used in slave mode only)
outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
}
void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
{
i2cSlaveReceive = i2cSlaveRx_func;
}
void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData))
{
i2cSlaveTransmit = i2cSlaveTx_func;
}
inline void i2cSendStart(void)
{
// send start condition
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
}
inline void i2cSendStop(void)
{
// transmit stop condition
// leave with TWEA on for slave receiving
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
}
inline void i2cWaitForComplete(void)
{
// wait for i2c interface to complete operation
while( !(inb(TWCR) & BV(TWINT)) );
}
inline void i2cSendByte(u08 data)
{
// save data to the TWDR
outb(TWDR, data);
// begin send
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
}
inline void i2cReceiveByte(u08 ackFlag)
{
// begin receive over i2c
if( ackFlag )
{
// ackFlag = TRUE: ACK the recevied data
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
}
else
{
// ackFlag = FALSE: NACK the recevied data
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
}
}
inline u08 i2cGetReceivedByte(void)
{
// retieve received data byte from i2c TWDR
return( inb(TWDR) );
}
inline u08 i2cGetStatus(void)
{
// retieve current i2c status from i2c TWSR
return( inb(TWSR) );
}
void i2cMasterSend(u08 deviceAddr, u08 length, u08* data)
{
u08 i;
// wait for interface to be ready
while(I2cState);
// set state
I2cState = I2C_MASTER_TX;
// save data
I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation
for(i=0; i<length; i++)
I2cSendData[i] = *data++;
I2cSendDataIndex = 0;
I2cSendDataLength = length;
// send start condition
i2cSendStart();
}
void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data)
{
u08 i;
// wait for interface to be ready
while(I2cState);
// set state
I2cState = I2C_MASTER_RX;
// save data
I2cDeviceAddrRW = (deviceAddr|0x01); // RW set: read operation
I2cReceiveDataIndex = 0;
I2cReceiveDataLength = length;
// send start condition
i2cSendStart();
// wait for data
while(I2cState);
// return data
for(i=0; i<length; i++)
*data++ = I2cReceiveData[i];
}
u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
{
u08 retval = I2C_OK;
// disable TWI interrupt
cbi(TWCR, TWIE);
// send start condition
i2cSendStart();
i2cWaitForComplete();
// send device address with write
i2cSendByte( deviceAddr & 0xFE );
i2cWaitForComplete();
// check if device is present and live
if( inb(TWSR) == TW_MT_SLA_ACK)
{
// send data
while(length)
{
i2cSendByte( *data++ );
i2cWaitForComplete();
length--;
}
}
else
{
// device did not ACK it's address,
// data will not be transferred
// return error
retval = I2C_ERROR_NODEV;
}
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
// enable TWI interrupt
sbi(TWCR, TWIE);
return retval;
}
u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
{
u08 retval = I2C_OK;
// disable TWI interrupt
cbi(TWCR, TWIE);
// send start condition
i2cSendStart();
i2cWaitForComplete();
// send device address with read
i2cSendByte( deviceAddr | 0x01 );
i2cWaitForComplete();
// check if device is present and live
if( inb(TWSR) == TW_MR_SLA_ACK)
{
// accept receive data and ack it
while(length > 1)
{
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*data++ = i2cGetReceivedByte();
// decrement length
length--;
}
// accept receive data and nack it (last-byte signal)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*data++ = i2cGetReceivedByte();
}
else
{
// device did not ACK it's address,
// data will not be transferred
// return error
retval = I2C_ERROR_NODEV;
}
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
// enable TWI interrupt
sbi(TWCR, TWIE);
return retval;
}
/*
void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)
{
// disable TWI interrupt
cbi(TWCR, TWIE);
// send start condition
i2cSendStart();
i2cWaitForComplete();
// if there's data to be sent, do it
if(sendlength)
{
// send device address with write
i2cSendByte( deviceAddr & 0xFE );
i2cWaitForComplete();
// send data
while(sendlength)
{
i2cSendByte( *senddata++ );
i2cWaitForComplete();
sendlength--;
}
}
// if there's data to be received, do it
if(receivelength)
{
// send repeated start condition
i2cSendStart();
i2cWaitForComplete();
// send device address with read
i2cSendByte( deviceAddr | 0x01 );
i2cWaitForComplete();
// accept receive data and ack it
while(receivelength > 1)
{
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*receivedata++ = i2cGetReceivedByte();
// decrement length
receivelength--;
}
// accept receive data and nack it (last-byte signal)
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*receivedata++ = i2cGetReceivedByte();
}
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
// enable TWI interrupt
sbi(TWCR, TWIE);
}
*/
//! I2C (TWI) interrupt service routine
SIGNAL(SIG_2WIRE_SERIAL)
{
// read status bits
u08 status = inb(TWSR) & TWSR_STATUS_MASK;
switch(status)
{
// Master General
case TW_START: // 0x08: Sent start condition
case TW_REP_START: // 0x10: Sent repeated start condition
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: M->START\r\n");
rprintfInit(uart1SendByte);
#endif
// send device address
i2cSendByte(I2cDeviceAddrRW);
break;
// Master Transmitter & Receiver status codes
case TW_MT_SLA_ACK: // 0x18: Slave address acknowledged
case TW_MT_DATA_ACK: // 0x28: Data acknowledged
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MT->SLA_ACK or DATA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
if(I2cSendDataIndex < I2cSendDataLength)
{
// send data
i2cSendByte( I2cSendData[I2cSendDataIndex++] );
}
else
{
// transmit stop condition, enable SLA ACK
i2cSendStop();
// set state
I2cState = I2C_IDLE;
}
break;
case TW_MR_DATA_NACK: // 0x58: Data received, NACK reply issued
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MR->DATA_NACK\r\n");
rprintfInit(uart1SendByte);
#endif
// store final received data byte
I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
// continue to transmit STOP condition
case TW_MR_SLA_NACK: // 0x48: Slave address not acknowledged
case TW_MT_SLA_NACK: // 0x20: Slave address not acknowledged
case TW_MT_DATA_NACK: // 0x30: Data not acknowledged
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MTR->SLA_NACK or MT->DATA_NACK\r\n");
rprintfInit(uart1SendByte);
#endif
// transmit stop condition, enable SLA ACK
i2cSendStop();
// set state
I2cState = I2C_IDLE;
break;
case TW_MT_ARB_LOST: // 0x38: Bus arbitration lost
//case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MT->ARB_LOST\r\n");
rprintfInit(uart1SendByte);
#endif
// release bus
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
// set state
I2cState = I2C_IDLE;
// release bus and transmit start when bus is free
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
break;
case TW_MR_DATA_ACK: // 0x50: Data acknowledged
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MR->DATA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
// store received data byte
I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
// fall-through to see if more bytes will be received
case TW_MR_SLA_ACK: // 0x40: Slave address acknowledged
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: MR->SLA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
if(I2cReceiveDataIndex < (I2cReceiveDataLength-1))
// data byte will be received, reply with ACK (more bytes in transfer)
i2cReceiveByte(TRUE);
else
// data byte will be received, reply with NACK (final byte in transfer)
i2cReceiveByte(FALSE);
break;
// Slave Receiver status codes
case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned
case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned
case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned
case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: SR->SLA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
// we are being addressed as slave for writing (data will be received from master)
// set state
I2cState = I2C_SLAVE_RX;
// prepare buffer
I2cReceiveDataIndex = 0;
// receive data byte and return ACK
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
break;
case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned
case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: SR->DATA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
// get previously received data byte
I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
// check receive buffer status
if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE)
{
// receive data byte and return ACK
i2cReceiveByte(TRUE);
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
}
else
{
// receive data byte and return NACK
i2cReceiveByte(FALSE);
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
}
break;
case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned
case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: SR->DATA_NACK\r\n");
rprintfInit(uart1SendByte);
#endif
// receive data byte and return NACK
i2cReceiveByte(FALSE);
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
break;
case TW_SR_STOP: // 0xA0: STOP or REPEATED START has been received while addressed as slave
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: SR->SR_STOP\r\n");
rprintfInit(uart1SendByte);
#endif
// switch to SR mode with SLA ACK
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
// i2c receive is complete, call i2cSlaveReceive
if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
// set state
I2cState = I2C_IDLE;
break;
// Slave Transmitter
case TW_ST_SLA_ACK: // 0xA8: own SLA+R has been received, ACK has been returned
case TW_ST_ARB_LOST_SLA_ACK: // 0xB0: GCA+R has been received, ACK has been returned
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: ST->SLA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
// we are being addressed as slave for reading (data must be transmitted back to master)
// set state
I2cState = I2C_SLAVE_TX;
// request data from application
if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
// reset data index
I2cSendDataIndex = 0;
// fall-through to transmit first data byte
case TW_ST_DATA_ACK: // 0xB8: data byte has been transmitted, ACK has been received
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: ST->DATA_ACK\r\n");
rprintfInit(uart1SendByte);
#endif
// transmit data byte
outb(TWDR, I2cSendData[I2cSendDataIndex++]);
if(I2cSendDataIndex < I2cSendDataLength)
// expect ACK to data byte
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
else
// expect NACK to data byte
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
break;
case TW_ST_DATA_NACK: // 0xC0: data byte has been transmitted, NACK has been received
case TW_ST_LAST_DATA: // 0xC8:
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: ST->DATA_NACK or LAST_DATA\r\n");
rprintfInit(uart1SendByte);
#endif
// all done
// switch to open slave
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
// set state
I2cState = I2C_IDLE;
break;
// Misc
case TW_NO_INFO: // 0xF8: No relevant state information
// do nothing
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: NO_INFO\r\n");
rprintfInit(uart1SendByte);
#endif
break;
case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition
#ifdef I2C_DEBUG
rprintfInit(uart1AddToTxBuffer);
rprintf("I2C: BUS_ERROR\r\n");
rprintfInit(uart1SendByte);
#endif
// reset internal hardware and release bus
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
// set state
I2cState = I2C_IDLE;
break;
}
}
eI2cStateType i2cGetState(void)
{
return I2cState;
}

View File

@ -1,129 +0,0 @@
/*! \file i2c.h \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */
//*****************************************************************************
//
// File Name : 'i2c.h'
// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware
// Author : Pascal Stang - Copyright (C) 2002-2003
// Created : 2002.06.25
// Revised : 2003.03.03
// Version : 0.9
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef I2C_H
#define I2C_H
#include "global.h"
// include project-specific configuration
#include "i2cconf.h"
// TWSR values (not bits)
// (taken from avr-libc twi.h - thank you Marek Michalkiewicz)
// Master
#define TW_START 0x08
#define TW_REP_START 0x10
// Master Transmitter
#define TW_MT_SLA_ACK 0x18
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_ACK 0x28
#define TW_MT_DATA_NACK 0x30
#define TW_MT_ARB_LOST 0x38
// Master Receiver
#define TW_MR_ARB_LOST 0x38
#define TW_MR_SLA_ACK 0x40
#define TW_MR_SLA_NACK 0x48
#define TW_MR_DATA_ACK 0x50
#define TW_MR_DATA_NACK 0x58
// Slave Transmitter
#define TW_ST_SLA_ACK 0xA8
#define TW_ST_ARB_LOST_SLA_ACK 0xB0
#define TW_ST_DATA_ACK 0xB8
#define TW_ST_DATA_NACK 0xC0
#define TW_ST_LAST_DATA 0xC8
// Slave Receiver
#define TW_SR_SLA_ACK 0x60
#define TW_SR_ARB_LOST_SLA_ACK 0x68
#define TW_SR_GCALL_ACK 0x70
#define TW_SR_ARB_LOST_GCALL_ACK 0x78
#define TW_SR_DATA_ACK 0x80
#define TW_SR_DATA_NACK 0x88
#define TW_SR_GCALL_DATA_ACK 0x90
#define TW_SR_GCALL_DATA_NACK 0x98
#define TW_SR_STOP 0xA0
// Misc
#define TW_NO_INFO 0xF8
#define TW_BUS_ERROR 0x00
// defines and constants
#define TWCR_CMD_MASK 0x0F
#define TWSR_STATUS_MASK 0xF8
// return values
#define I2C_OK 0x00
#define I2C_ERROR_NODEV 0x01
// types
typedef enum
{
I2C_IDLE = 0, I2C_BUSY = 1,
I2C_MASTER_TX = 2, I2C_MASTER_RX = 3,
I2C_SLAVE_TX = 4, I2C_SLAVE_RX = 5
} eI2cStateType;
// functions
//! Initialize I2C (TWI) interface
void i2cInit(void);
//! Set the I2C transaction bitrate (in KHz)
void i2cSetBitrate(u16 bitrateKHz);
// I2C setup and configurations commands
//! Set the local (AVR processor's) I2C device address
void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn);
//! Set the user function which handles receiving (incoming) data as a slave
void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData));
//! Set the user function which handles transmitting (outgoing) data as a slave
void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData));
// Low-level I2C transaction commands
//! Send an I2C start condition in Master mode
void i2cSendStart(void);
//! Send an I2C stop condition in Master mode
void i2cSendStop(void);
//! Wait for current I2C operation to complete
void i2cWaitForComplete(void);
//! Send an (address|R/W) combination or a data byte over I2C
void i2cSendByte(u08 data);
//! Receive a data byte over I2C
// ackFlag = TRUE if recevied data should be ACK'ed
// ackFlag = FALSE if recevied data should be NACK'ed
void i2cReceiveByte(u08 ackFlag);
//! Pick up the data that was received with i2cReceiveByte()
u08 i2cGetReceivedByte(void);
//! Get current I2c bus status from TWSR
u08 i2cGetStatus(void);
// high-level I2C transaction commands
//! send I2C data to a device on the bus
void i2cMasterSend(u08 deviceAddr, u08 length, u08 *data);
//! receive I2C data from a device on the bus
void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data);
//! send I2C data to a device on the bus (non-interrupt based)
u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data);
//! receive I2C data from a device on the bus (non-interrupt based)
u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data);
//! Get the current high-level state of the I2C interface
eI2cStateType i2cGetState(void);
#endif

View File

@ -1,60 +0,0 @@
/*! \file i2ceeprom.c \brief Interface for standard I2C EEPROM memories. */
//*****************************************************************************
//
// File Name : 'i2ceeprom.c'
// Title : Interface for standard I2C EEPROM memories
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.04.23
// Revised : 2003.04.23
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "i2c.h"
#include "i2ceeprom.h"
// Standard I2C bit rates are:
// 100KHz for slow speed
// 400KHz for high speed
// functions
void i2ceepromInit(void)
{
// although there is no code here
// don't forget to initialize the I2C interface itself
}
u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr)
{
u08 packet[2];
// prepare address
packet[0] = (memAddr>>8);
packet[1] = (memAddr&0x00FF);
// send memory address we wish to access to the memory chip
i2cMasterSendNI(i2cAddr, 2, packet);
// retrieve the data at this memory address
i2cMasterReceiveNI(i2cAddr, 1, packet);
// return data
return packet[0];
}
void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data)
{
u08 packet[3];
// prepare address + data
packet[0] = (memAddr>>8);
packet[1] = (memAddr&0x00FF);
packet[2] = data;
// send memory address we wish to access to the memory chip
// along with the data we wish to write
i2cMasterSendNI(i2cAddr, 3, packet);
}

View File

@ -1,34 +0,0 @@
/*! \file i2ceeprom.h \brief Interface for standard I2C EEPROM memories. */
//*****************************************************************************
//
// File Name : 'i2ceeprom.h'
// Title : Interface for standard I2C EEPROM memories
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.04.23
// Revised : 2003.04.23
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef I2CEEPROM_H
#define I2CEEPROM_H
#include "global.h"
// functions
//! Initialize I2C EEPROM interface
void i2ceepromInit(void);
//! In the I2C EEPROM at [i2cAddr], read a byte from memory location [memAddr]
u08 i2ceepromReadByte(u08 i2cAddr, u32 memAddr);
//! In the I2C EEPROM at [i2cAddr], write a byte [data] to the memory location [memAddr]
void i2ceepromWriteByte(u08 i2cAddr, u32 memAddr, u08 data);
#endif

View File

@ -1,176 +0,0 @@
/*! \file i2csw.c \brief Software-driven I2C interface using port pins. */
//*****************************************************************************
//
// File Name : 'i2csw.c'
// Title : Software-driven I2C interface using port pins
// Author : Pascal Stang
// Created : 11/22/2000
// Revised : 5/2/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include "i2csw.h"
// Standard I2C bit rates are:
// 100KHz for slow speed
// 400KHz for high speed
//#define QDEL delay(5) // i2c quarter-bit delay
//#define HDEL delay(10) // i2c half-bit delay
// i2c quarter-bit delay
#define QDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
// i2c half-bit delay
#define HDEL asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
#define I2C_SDL_LO cbi( SDAPORT, SDA)
#define I2C_SDL_HI sbi( SDAPORT, SDA)
#define I2C_SCL_LO cbi( SCLPORT, SCL);
#define I2C_SCL_HI sbi( SCLPORT, SCL);
#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO;
#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;
/*
void i2ct(void)
{
HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
}
void i2cstart(void)
{
I2C_SDL_LO; QDEL; I2C_SCL_LO;
}
void i2cstop(void)
{
HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;
}
#define I2C_SCL_TOGGLE i2ct();
#define I2C_START i2cstart();
#define I2C_STOP i2cstop();
*/
UINT i2cPutbyte(u08 b)
{
int i;
for (i=7;i>=0;i--)
{
if ( b & (1<<i) )
I2C_SDL_HI;
else
I2C_SDL_LO; // address bit
I2C_SCL_TOGGLE; // clock HI, delay, then LO
}
I2C_SDL_HI; // leave SDL HI
// added
cbi(SDADDR, SDA); // change direction to input on SDA line (may not be needed)
HDEL;
I2C_SCL_HI; // clock back up
b = inb(SDAPIN) & (1<<SDA); // get the ACK bit
HDEL;
I2C_SCL_LO; // not really ??
sbi(SDADDR, SDA); // change direction back to output
HDEL;
return (b == 0); // return ACK value
}
u08 i2cGetbyte(UINT last)
{
int i;
u08 c,b = 0;
I2C_SDL_HI; // make sure pullups are ativated
cbi(SDADDR, SDA); // change direction to input on SDA line (may not be needed)
for(i=7;i>=0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
c = inb(SDAPIN) & (1<<SDA);
b <<= 1;
if(c) b |= 1;
HDEL;
I2C_SCL_LO; // clock LO
}
sbi(SDADDR, SDA); // change direction to output on SDA line
if (last)
I2C_SDL_HI; // set NAK
else
I2C_SDL_LO; // set ACK
I2C_SCL_TOGGLE; // clock pulse
I2C_SDL_HI; // leave with SDL HI
return b; // return received byte
}
//************************
//* I2C public functions *
//************************
//! Initialize I2C communication
void i2cInit(void)
{
sbi( SDADDR, SDA); // set SDA as output
sbi( SCLDDR, SCL); // set SCL as output
I2C_SDL_HI; // set I/O state and pull-ups
I2C_SCL_HI; // set I/O state and pull-ups
}
//! Send a byte sequence on the I2C bus
void i2cSend(u08 device, u08 subAddr, u08 length, u08 *data)
{
I2C_START; // do start transition
i2cPutbyte(device); // send DEVICE address
i2cPutbyte(subAddr); // and the subaddress
// send the data
while (length--)
i2cPutbyte(*data++);
I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
}
//! Retrieve a byte sequence on the I2C bus
void i2cReceive(u08 device, u08 subAddr, u08 length, u08 *data)
{
int j = length;
u08 *p = data;
I2C_START; // do start transition
i2cPutbyte(device); // send DEVICE address
i2cPutbyte(subAddr); // and the subaddress
HDEL;
I2C_SCL_HI; // do a repeated START
I2C_START; // transition
i2cPutbyte(device | READ); // resend DEVICE, with READ bit set
// receive data bytes
while (j--)
*p++ = i2cGetbyte(j == 0);
I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
}

View File

@ -1,40 +0,0 @@
/*! \file i2csw.h \brief software-driven I2C interface using port pins. */
//*****************************************************************************
//
// File Name : 'i2csw.h'
// Title : software-driven I2C interface using port pins
// Author : Pascal Stang
// Created : 11/22/2000
// Revised : 5/2/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef I2CSW_H
#define I2CSW_H
#include "global.h"
// include project-dependent settings
#include "i2cswconf.h"
// defines and constants
#define READ 0x01 // I2C READ bit
// functions
// initialize I2C interface pins
void i2cInit(void);
// send I2C data to <device> register <sub>
void i2cSend(BYTE device, BYTE sub, BYTE length, BYTE *data);
// receive I2C data from <device> register <sub>
void i2cReceive(BYTE device, BYTE sub, BYTE length, BYTE *data);
#endif

View File

@ -1,134 +0,0 @@
<html>
<head>
<title>Procyon AVRlib - C-Language Function Library for Atmel AVR Processors</title>
</head>
<body>
<!--#config timefmt="%A %B %d, %Y" -->
<h1 align="center"><font color="#990000"><b><font color="#0066CC">Procyon AVRlib</font></b></font><font size="4" face="Arial" color="#990000"><b><br>
</b></font><font size="4" color="#990000"><b>C-Language Function Library for
Atmel AVR Processors</b></font></h1>
<center>
Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
<hr>
<ul>
<li><b>AVRlib is a library of easy-to-use C functions for a variety of common
and uncommon tasks using AVR processors. </b></li>
<li>The goal of AVRlib is to allow programmers to work quickly towards their
end goal by reducing the time needed to write basic support functions and
code. </li>
<li> Most AVRlib header (*.h) files have lengthy descriptions of how to use
the supplied library functions. All code (*.c) files are heavily commented
with additional information. </li>
<li> Documentation is still being improved and refined on many libraries. When
getting familiar with a library, look first at the HTML docs and any example
code that is available in the examples directory. Then look inside the *.h
and *conf.h files, and then the *.c file for that library for more details
and documentation.</li>
<li> Significant example code is included in <i>avrlib.zip.</i> The example
code is heavily commented and strives to illustrate how to use various AVRlib
function libraries.</li>
<li><font color="#FF0000"><strong>Download AVRlib (with docs and code examples)</strong>
</font>
<ul>
<li><a href="avrlib.zip">AVRlib (zip file, 1MB, <!--#flastmod virtual="avrlib.zip"-->)</a></li>
<li><a href="avrlib_setup.exe">AVRlib (win32 installer package, 1MB,
<!--#flastmod virtual="avrlib.zip"-->
)</a></li>
</ul>
</li>
<li><a href="docs/html/index.html">On-line HTML Documentation</a></li>
<li> <a href="release_notes.html">Release Notes</a></li>
<li> <a href="install.html">AVRlib Install Guide</a> for manual installation
of zip file</li>
</ul>
<hr>
<div align="center">
<h3><font color="#0066CC"><b>Procyon AVRlib Overview</b></font></h3>
</div>
<table border="1" width="100%">
<tr>
<td width="50%" bgcolor="#3C2D74"><font color="#FFFFFF"><b>General</b></font></td>
<td width="50%" bgcolor="#3C2D74"><font color="#FFFFFF"><b>AVR Built-In Peripheral
Drivers </b></font></td>
</tr>
<tr>
<td width="50%">
<ul>
<li>Byte Buffering (circular)</li>
<li>Bit Buffering (linear)</li>
<li>Printf and other formatted print functions</li>
<li>VT100 Terminal Output</li>
<li>Command Line Interface</li>
<li>FAT16/32 File System (support is read-only for now)</li>
<li>STX/ETX Packet Protocol</li>
<li>Fixed-Point Math Library (basic operations only)</li>
</ul>
</td>
<td width="50%">
<ul>
<li>Timers (with PWM, interrupt management)</li>
<li>UART (interrupt driven)</li>
<li>A/D Converter</li>
<li>I2C Master/Slave (interrupt and non-intr)</li>
<li>SPI Interface</li>
<li>External Interrupts</li>
</ul>
</td>
</tr>
<tr>
<td width="50%" bgcolor="#3C2D74"><font color="#FFFFFF"><b> External Hardware
Device Drivers</b></font></td>
<td width="50%" bgcolor="#3C2D74"><font color="#FFFFFF"><b>AVR Software-Emulated Devices</b></font></td>
</tr>
<tr>
<td width="50%">
<ul>
<li>Character LCD Modules (HD44780-based)</li>
<li>I2C EEPROM Memories</li>
<li>SPI EEPROM Memories</li>
<li>MMC/SD Card Interface (SPI mode)</li>
<li>LIS3L02 ST Accelerometer</li>
<li>IDE/ATA Interface (for hard disks and CF cards)</li>
<li>Quadrature Encoders</li>
<li>RC-Servos (up to 8 channels)</li>
<li>STA013 MP3 Decoder Chip</li>
<li>GPS Receivers (via serial port)
<ul>
<li>NMEA-0813 Protocol</li>
<li>Trimble TSIP Protocol</li>
</ul>
</li>
<li>Graphic LCD Modules
<ul>
<li>KS0108/HD61202 Controller</li>
<li>T6963 Controller</li>
<li>LCD Fonts and Symbols</li>
</ul>
</li>
</ul>
</td>
<td width="50%"> <ul>
<li>I2c Master (Bit-Bang)</li>
<li>UART (software-based, timer interrupt driven)</li>
<li>Pulse Output (timer-based, variable frequency)</li>
<li>Intel-type Memory Bus (Address & Data Buses + nRD,nWR)</li>
</ul>
</td>
</tr>
</table>
<hr>
<center>
Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
</body>
</html>

View File

@ -1,154 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SCU Robotic Systems Laboratory - Installing Procyon AVRlib</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<!--#config timefmt="%a %b %d, %Y" -->
<h1>Installing Procyon AVRlib</h1>
<h2>Sections</h2>
<ol>
<li><a href="#1">Overview</a></li>
<li><a href="#2">Downloading</a></li>
<li><a href="#3">Installing</a></li>
<li><a href="#4">Testing</a></li>
</ol>
<center>Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
<hr>
<h3><a name="1"></a>1. Overview</h3>
<blockquote>
<p>Procyon AVRlib is an open-source collection of C-language function libraries
for the Atmel AVR series processors. The goal of AVRlib is to provide the
programmer with a code base which performs the most often needed tasks in
embedded system programming. Hopefully, this will allow the programmer to
focus on high-level operation of their code rather than get bogged down in
the details of low-level code.</p>
<p>In short, AVRlib is a bunch of functions that do things commonly needed in
embedded systems. Despite the learning curve of getting started, for most
projects, using AVRlib will shorten the time spent programming and/or improve
the quality or functionality of the final product.</p>
<p>AVRlib functions are available for a wide variety of tasks and purposes.
In general, AVRlib tries to address the following kinds of needs:</p>
<ul>
<li>Functions which control or interface to AVR processor hardware (like timers,
uarts, the a2d converter, etc)</li>
<li>Functions which interface to or drive devices often used in embedded systems
(like LCDs, hard disks, gps units, etc)</li>
<li>Functions which create higher-level functionality from processor resources
(like pulse generation, software uarts, software i2c bus, etc)</li>
</ul>
<p>For a partial list of currently available function libraries see the <a href="index.html">AVRlib
Main Page</a>.</p>
</blockquote>
<h3><a name="2"></a>2. Downloading</h3>
<blockquote>
<p>AVRlib is currently available as individual files, or a complete zip file.
Both are available from the <a href="index.html">AVRlib Main Page</a>.</p>
<p><strong><font color="#FF0000">Downloading the complete <a href="avrlib.zip">avrlib.zip</a>
file is highly recommended as documentation and code examples are included
in the zip.</font></strong></p>
</blockquote>
<h3><a name="3"></a>3. Installing</h3>
<blockquote>
<p><strong><font color="#FF0000">This installation for AVRlib assumes you have
already installed the AVR-GCC or WinAVR compiler and successfully tested it.</font></strong></p>
<p>You can install AVRlib anywhere you like, however, it's suggested that you
install it in a directory alongside your own AVR code projects. Create or
choose a top-level directory to hold both AVRlib and the project folders which
you will create to hold the code for each individual project you work on.
The directory you choose should not contain spaces in its name or path. Some
examples are: </p>
<pre>
c:\Code\AVR <font color="#009900">(GOOD)</font>
c:\My Code <font color="#FF0000">(NOT RECOMMENDED - HAS SPACES IN PATH)</font>
</pre>
<p>From the download step you should have an <strong>avrlib.zip</strong> file.
Unzip this file into the code directory you chose above. Be sure to preserve
the internal directory structure of the zip file when you unzip it. Afterward,
you can delete avrlib.zip but you may want to keep it for later re-installs
or as a backup.</p>
<p>You should now have an <strong>avrlib</strong> directory where you installed
AVRlib. If you have some time, get familiar with what's inside some of the
directories. Your directories should look something like this:</p>
<pre>
c:\Code\AVR\avrlib <font color="#0000FF"><-- AVRlib header and code files</font>
c:\Code\AVR\avrlib\conf <font color="#0000FF"><-- AVRlib template configuration files</font>
c:\Code\AVR\avrlib\docs <font color="#0000FF"><-- AVRlib documentation</font>
c:\Code\AVR\avrlib\examples <font color="#0000FF"><-- AVRlib example applications</font>
c:\Code\AVR\avrlib\make <font color="#0000FF"><-- AVRlib makefile include (avrproj_make file in here)</font></pre>
<p>Finally, you need to create an environment variable <strong>AVRLIB</strong>
which points to the directory where you &quot;installed&quot; or unzipped
the AVRlib files so the compiler can find them. An example might be:</p>
<pre>AVRLIB = c:/code/avr/avrlib <font color="#0000FF"><-- change to actual AVRlib install directory</font>
</pre>
<p>If you are unsure how to set environment variables on your system, look at
the WinAVR/AVR-GCC installation guide elsewhere on this site or consult the
web.</p>
<p>AVRlib installation is complete!</p>
</blockquote>
<h3><a name="4"></a>4. Testing</h3>
<blockquote>
<p>There are a few simple steps you can take to verify that AVRlib is properly
installed:<br>
<font color="#FF0000"><strong>(This assumes you have previously installed
and tested the AVR-GCC or WinAVR compiler)</strong></font></p>
<ul>
<li>Open a Command Prompt (find it in your <strong>Start Menu</strong> or
select <strong>Run</strong>, and run <strong>cmd.exe</strong>) </li>
<li>Change directories to the location where you installed AVRlib. For example:<br>
<strong>cd c:\Code\AVR\AVRlib</strong></li>
<li>Go into the examples directory. <strong>cd examples</strong></li>
<li>Pick an example to try compiling such as rprintf and change to that directory.
<strong>cd rprintf</strong></li>
<li>Type <strong>make clean</strong> at the prompt</li>
<li>Type <strong>make</strong></li>
<li>If your output looked like this then you just compiled your first AVRlib
program:
<pre>
C:\Code\AVR\avrlib\examples\rprintf>make
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=rpri
ntftest.lst -mmcu=atmega323 -I. rprintftest.c -o rprintftest.o
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
ode/avr/avrlib/buffer.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/buffer.c -o c:/
code/avr/avrlib/buffer.o
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
ode/avr/avrlib/uart.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/uart.c -o c:/code
/avr/avrlib/uart.o
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
ode/avr/avrlib/rprintf.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/rprintf.c -o c
:/code/avr/avrlib/rprintf.o
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
ode/avr/avrlib/timer.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/timer.c -o c:/co
de/avr/avrlib/timer.o
avr-gcc -c -g -Os -Wall -Wstrict-prototypes -Ic:/code/avr/avrlib -Wa,-ahlms=c:/c
ode/avr/avrlib/vt100.lst -mmcu=atmega323 -I. c:/code/avr/avrlib/vt100.c -o c:/co
de/avr/avrlib/vt100.o
avr-gcc c:/code/avr/avrlib/buffer.o c:/code/avr/avrlib/uart.o c:/code/avr/avrli
b/rprintf.o c:/code/avr/avrlib/timer.o c:/code/avr/avrlib/vt100.o rprintftest.o
-Wl,-Map=rprintftest.map,--cref -mmcu=atmega323 -o rprintftest.elf
avr-objcopy -O ihex -R .eeprom rprintftest.elf rprintftest.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section
-lma .eeprom=0 -O ihex rprintftest.elf rprintftest.eep
avr-size rprintftest.elf
text data bss dec hex filename
9596 0 192 9788 263c rprintftest.elf
Errors: none
rm c:/code/avr/avrlib/vt100.o c:/code/avr/avrlib/rprintf.o c:/code/avr/avrlib/ua
rt.o c:/code/avr/avrlib/timer.o c:/code/avr/avrlib/buffer.o
C:\Code\AVR\avrlib\examples\rprintf>
</pre>
</li>
<strong>AVRlib is ready to use!</strong>
</ul>
</blockquote>
<hr>
<center>Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
</body>
</html>

View File

@ -1,381 +0,0 @@
/*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */
//*****************************************************************************
//
// File Name : 'ks0108.c'
// Title : Graphic LCD driver for HD61202/KS0108 displays
// Author : Pascal Stang - Copyright (C) 2001-2003
// Date : 10/19/2002
// Revised : 5/5/2003
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
// AVR specific includes
#include <avr/io.h>
#include <avr/interrupt.h>
#endif
#include "global.h"
#include "ks0108.h"
// global variables
GrLcdStateType GrLcdState;
/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/
void glcdInitHW(void)
{
// initialize I/O ports
// if I/O interface is in use
#ifdef GLCD_PORT_INTERFACE
//TODO: make setup of chip select lines contingent on how
// many controllers are actually in the display
// initialize LCD control lines levels
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
// initialize LCD control port to output
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_E);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS2);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS3);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RESET);
// initialize LCD data
outb(GLCD_DATA_PORT, 0x00);
// initialize LCD data port to output
outb(GLCD_DATA_DDR, 0xFF);
#endif
}
void glcdControllerSelect(u08 controller)
{
#ifdef GLCD_PORT_INTERFACE
//TODO: make control of chip select lines contingent on how
// many controllers are actually in the display
// unselect all controllers
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
// select requested controller
switch(controller)
{
case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); break;
case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); break;
case 2: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); break;
case 3: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); break;
default: break;
}
#endif
}
void glcdBusyWait(u08 controller)
{
#ifdef GLCD_PORT_INTERFACE
cli();
// wait until LCD busy bit goes to zero
// select the controller chip
glcdControllerSelect(controller);
// do a read from control register
outb(GLCD_DATA_PORT, 0xFF);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
outb(GLCD_DATA_DDR, 0x00);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
asm volatile ("nop"); asm volatile ("nop");
while(inb(GLCD_DATA_PIN) & GLCD_STATUS_BUSY)
{
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
}
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
outb(GLCD_DATA_DDR, 0xFF);
sei();
#else
// sbi(MCUCR, SRW); // enable RAM waitstate
// wait until LCD busy bit goes to zero
while(*(volatile unsigned char *)
(GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) & GLCD_STATUS_BUSY);
// cbi(MCUCR, SRW); // disable RAM waitstate
#endif
}
void glcdControlWrite(u08 controller, u08 data)
{
#ifdef GLCD_PORT_INTERFACE
cli();
glcdBusyWait(controller); // wait until LCD not busy
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
outb(GLCD_DATA_DDR, 0xFF);
outb(GLCD_DATA_PORT, data);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
sei();
#else
//sbi(MCUCR, SRW); // enable RAM waitstate
glcdBusyWait(controller); // wait until LCD not busy
*(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
}
u08 glcdControlRead(u08 controller)
{
register u08 data;
#ifdef GLCD_PORT_INTERFACE
cli();
glcdBusyWait(controller); // wait until LCD not busy
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
outb(GLCD_DATA_DDR, 0x00);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
data = inb(GLCD_DATA_PIN);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
outb(GLCD_DATA_DDR, 0xFF);
sei();
#else
//sbi(MCUCR, SRW); // enable RAM waitstate
glcdBusyWait(controller); // wait until LCD not busy
data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
return data;
}
void glcdDataWrite(u08 data)
{
register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
#ifdef GLCD_PORT_INTERFACE
cli();
glcdBusyWait(controller); // wait until LCD not busy
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
outb(GLCD_DATA_DDR, 0xFF);
outb(GLCD_DATA_PORT, data);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
sei();
#else
//sbi(MCUCR, SRW); // enable RAM waitstate
glcdBusyWait(controller); // wait until LCD not busy
*(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
// increment our local address counter
GrLcdState.ctrlr[controller].xAddr++;
GrLcdState.lcdXAddr++;
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
{
GrLcdState.lcdYAddr++;
glcdSetYAddress(GrLcdState.lcdYAddr);
glcdSetXAddress(0);
}
}
u08 glcdDataRead(void)
{
register u08 data;
register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
#ifdef GLCD_PORT_INTERFACE
cli();
glcdBusyWait(controller); // wait until LCD not busy
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
outb(GLCD_DATA_DDR, 0x00);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
asm volatile ("nop"); asm volatile ("nop");
data = inb(GLCD_DATA_PIN);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sei();
#else
//sbi(MCUCR, SRW); // enable RAM waitstate
glcdBusyWait(controller); // wait until LCD not busy
data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
// increment our local address counter
GrLcdState.ctrlr[controller].xAddr++;
GrLcdState.lcdXAddr++;
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
{
GrLcdState.lcdYAddr++;
glcdSetYAddress(GrLcdState.lcdYAddr);
glcdSetXAddress(0);
}
return data;
}
void glcdReset(u08 resetState)
{
// reset lcd if argument is true
// run lcd if argument is false
#ifdef GLCD_PORT_INTERFACE
if(resetState)
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
else
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
#endif
}
void glcdSetXAddress(u08 xAddr)
{
u08 i;
// record address change locally
GrLcdState.lcdXAddr = xAddr;
// clear y (col) address on all controllers
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_SET_Y_ADDR | 0x00);
GrLcdState.ctrlr[i].xAddr = 0;
}
// set y (col) address on destination controller
glcdControlWrite((GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS),
GLCD_SET_Y_ADDR | (GrLcdState.lcdXAddr & 0x3F));
}
void glcdSetYAddress(u08 yAddr)
{
u08 i;
// record address change locally
GrLcdState.lcdYAddr = yAddr;
// set page address for all controllers
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_SET_PAGE | yAddr);
}
}
/*************************************************************/
/********************* PUBLIC FUNCTIONS **********************/
/*************************************************************/
void glcdInit()
{
u08 i;
// initialize hardware
glcdInitHW();
// bring lcd out of reset
glcdReset(FALSE);
// Turn on LCD
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_ON_CTRL | GLCD_ON_DISPLAY);
}
// clear lcd
glcdClearScreen();
// initialize positions
glcdHome();
}
void glcdHome(void)
{
u08 i;
// initialize addresses/positions
glcdStartLine(0);
glcdSetAddress(0,0);
// initialize local data structures
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
GrLcdState.ctrlr[i].xAddr = 0;
GrLcdState.ctrlr[i].yAddr = 0;
}
}
void glcdClearScreen(void)
{
u08 pageAddr;
u08 xAddr;
// clear LCD
// loop through all pages
for(pageAddr=0; pageAddr<(GLCD_YPIXELS>>3); pageAddr++)
{
// set page address
glcdSetAddress(0, pageAddr);
// clear all lines of this page of display memory
for(xAddr=0; xAddr<GLCD_XPIXELS; xAddr++)
{
glcdDataWrite(0x00);
}
}
}
void glcdStartLine(u08 start)
{
glcdControlWrite(0, GLCD_START_LINE | start);
glcdControlWrite(1, GLCD_START_LINE | start);
}
void glcdSetAddress(u08 x, u08 yLine)
{
// set addresses
glcdSetYAddress(yLine);
glcdSetXAddress(x);
}
void glcdGotoChar(u08 line, u08 col)
{
glcdSetAddress(col*6, line);
}
void glcdDelay(u16 p) // 1-8us ...2-13us ...5-31us
{ // 10-60us ...50-290us
unsigned int i; // 100-580us ...500-2,9ms
unsigned char j; // 1000-5,8ms ...5000-29ms
// 10000-56ms ...30000-170ms
// 50000-295ms...60000-345ms
// for (i = 0; i < p; i++) for (j = 0; j < 10; j++) asm volatile ("nop");
for (i = 0; i < p; i++) for (j = 0; j < 10; j++);
}
// Higher level functionality has been moved to the API-layer glcd.c/glcd.h

View File

@ -1,86 +0,0 @@
/*! \file ks0108.h \brief Graphic LCD driver for HD61202/KS0108 displays. */
//*****************************************************************************
//
// File Name : 'ks0108.h'
// Title : Graphic LCD driver for HD61202/KS0108 displays
// Author : Pascal Stang - Copyright (C) 2001-2003
// Date : 10/19/2002
// Revised : 5/1/2003
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef KS0108_H
#define KS0108_H
#include "global.h"
#include "ks0108conf.h"
// HD61202/KS0108 command set
#define GLCD_ON_CTRL 0x3E // 0011111X: lcd on/off control
#define GLCD_ON_DISPLAY 0x01 // DB0: turn display on
#define GLCD_START_LINE 0xC0 // 11XXXXXX: set lcd start line
#define GLCD_SET_PAGE 0xB8 // 10111XXX: set lcd page (X) address
#define GLCD_SET_Y_ADDR 0x40 // 01YYYYYY: set lcd Y address
#define GLCD_STATUS_BUSY 0x80 // (1)->LCD IS BUSY
#define GLCD_STATUS_ONOFF 0x20 // (0)->LCD IS ON
#define GLCD_STATUS_RESET 0x10 // (1)->LCD IS RESET
// determine the number of controllers
// (make sure we round up for partial use of more than one controller)
#define GLCD_NUM_CONTROLLERS ((GLCD_XPIXELS+GLCD_CONTROLLER_XPIXELS-1)/GLCD_CONTROLLER_XPIXELS)
// typedefs/structures
typedef struct struct_GrLcdCtrlrStateType
{
unsigned char xAddr;
unsigned char yAddr;
} GrLcdCtrlrStateType;
typedef struct struct_GrLcdStateType
{
unsigned char lcdXAddr;
unsigned char lcdYAddr;
GrLcdCtrlrStateType ctrlr[GLCD_NUM_CONTROLLERS];
} GrLcdStateType;
// function prototypes
void glcdInitHW(void);
void glcdBusyWait(u08 controller);
void glcdControlWrite(u08 controller, u08 data);
u08 glcdControlRead(u08 controller);
void glcdDataWrite(u08 data);
u08 glcdDataRead(void);
void glcdSetXAddress(u08 xAddr);
void glcdSetYAddress(u08 yAddr);
//! Initialize the display, clear it, and prepare it for access
void glcdInit(void);
//! Clear the display
void glcdClearScreen(void);
//! Set display memory access point back to upper,left corner
void glcdHome(void);
//! Set display memory access point to row [line] and column [col] assuming 5x7 font
void glcdGotoChar(u08 line, u08 col);
//! Set display memory access point to [x] horizontal pixel and [y] vertical line
void glcdSetAddress(u08 x, u08 yLine);
//! Set display memory access point to row [line] and column [col] assuming 5x7 font
void glcdStartLine(u08 start);
//! Generic delay routine for timed glcd access
void glcdDelay(u16 p);
#endif

View File

@ -1,469 +0,0 @@
/*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */
//*****************************************************************************
//
// File Name : 'lcd.c'
// Title : Character LCD driver for HD44780/SED1278 displays
// (usable in mem-mapped, or I/O mode)
// Author : Pascal Stang
// Created : 11/22/2000
// Revised : 4/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "global.h"
#include "timer.h"
#include "lcd.h"
// custom LCD characters
unsigned char __attribute__ ((progmem)) LcdCustomChar[] =
{
0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block
0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars
0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow
0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow
0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character
0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00, // 13. animated play icon frame 0
0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00, // 14. animated play icon frame 1
0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00, // 15. animated play icon frame 2
0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00, // 16. animated play icon frame 3
};
/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/
void lcdInitHW(void)
{
// initialize I/O ports
// if I/O interface is in use
#ifdef LCD_PORT_INTERFACE
// initialize LCD control lines
cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
cbi(LCD_CTRL_PORT, LCD_CTRL_E);
// initialize LCD control lines to output
sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
sbi(LCD_CTRL_DDR, LCD_CTRL_E);
// initialize LCD data port to input
// initialize LCD data lines to pull-up
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
#else
// enable external memory bus if not already enabled
sbi(MCUCR, SRE); // enable bus interface
#endif
}
void lcdBusyWait(void)
{
// wait until LCD busy bit goes to zero
// do a read from control register
#ifdef LCD_PORT_INTERFACE
cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
while(inb(LCD_DATA_PIN) & 1<<LCD_BUSY)
{
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
#ifdef LCD_DATA_4BIT // do an extra clock for 4 bit reads
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
#endif
}
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
// leave data lines in input mode so they can be most easily used for other purposes
#else
// memory bus read
// sbi(MCUCR, SRW); // enable RAM waitstate
// wait until LCD busy bit goes to zero
while( (*((volatile unsigned char *) (LCD_CTRL_ADDR))) & (1<<LCD_BUSY) );
// cbi(MCUCR, SRW); // disable RAM waitstate
#endif
}
void lcdControlWrite(u08 data)
{
// write the control byte to the display controller
#ifdef LCD_PORT_INTERFACE
lcdBusyWait(); // wait until LCD not busy
cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write"
#ifdef LCD_DATA_4BIT
// 4 bit write
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) ); // output data, low 4 bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#else
// 8 bit write
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_DDR, 0xFF); // set data I/O lines to output (8bit)
outb(LCD_DATA_POUT, data); // output data, 8bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#endif
// leave data lines in input mode so they can be most easily used for other purposes
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
#else
// memory bus write
//sbi(MCUCR, SRW); // enable RAM waitstate
lcdBusyWait(); // wait until LCD not busy
*((volatile unsigned char *) (LCD_CTRL_ADDR)) = data;
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
}
u08 lcdControlRead(void)
{
// read the control byte from the display controller
register u08 data;
#ifdef LCD_PORT_INTERFACE
lcdBusyWait(); // wait until LCD not busy
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
#ifdef LCD_DATA_4BIT
// 4 bit read
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#else
// 8 bit read
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data = inb(LCD_DATA_PIN); // input data, 8bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#endif
// leave data lines in input mode so they can be most easily used for other purposes
#else
//sbi(MCUCR, SRW); // enable RAM waitstate
lcdBusyWait(); // wait until LCD not busy
data = *((volatile unsigned char *) (LCD_CTRL_ADDR));
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
return data;
}
void lcdDataWrite(u08 data)
{
// write a data byte to the display
#ifdef LCD_PORT_INTERFACE
lcdBusyWait(); // wait until LCD not busy
sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data"
cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write"
#ifdef LCD_DATA_4BIT
// 4 bit write
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) ); // output data, low 4 bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#else
// 8 bit write
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
outb(LCD_DATA_DDR, 0xFF); // set data I/O lines to output (8bit)
outb(LCD_DATA_POUT, data); // output data, 8bits
LCD_DELAY; // wait
LCD_DELAY; // wait
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#endif
// leave data lines in input mode so they can be most easily used for other purposes
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
#else
// memory bus write
//sbi(MCUCR, SRW); // enable RAM waitstate
lcdBusyWait(); // wait until LCD not busy
*((volatile unsigned char *) (LCD_DATA_ADDR)) = data;
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
}
u08 lcdDataRead(void)
{
// read a data byte from the display
register u08 data;
#ifdef LCD_PORT_INTERFACE
lcdBusyWait(); // wait until LCD not busy
#ifdef LCD_DATA_4BIT
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
#else
outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
#endif
sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data"
sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
#ifdef LCD_DATA_4BIT
// 4 bit read
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#else
// 8 bit read
sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
LCD_DELAY; // wait
data = inb(LCD_DATA_PIN); // input data, 8bits
cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
#endif
// leave data lines in input mode so they can be most easily used for other purposes
#else
// memory bus read
//sbi(MCUCR, SRW); // enable RAM waitstate
lcdBusyWait(); // wait until LCD not busy
data = *((volatile unsigned char *) (LCD_DATA_ADDR));
//cbi(MCUCR, SRW); // disable RAM waitstate
#endif
return data;
}
/*************************************************************/
/********************* PUBLIC FUNCTIONS **********************/
/*************************************************************/
void lcdInit()
{
// initialize hardware
lcdInitHW();
// LCD function set
lcdControlWrite(LCD_FUNCTION_DEFAULT);
// clear LCD
lcdControlWrite(1<<LCD_CLR);
delay(60000); // wait 60ms
// set entry mode
lcdControlWrite(1<<LCD_ENTRY_MODE | 1<<LCD_ENTRY_INC);
// set display to on
//lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY | 1<<LCD_ON_BLINK);
lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY );
// move cursor to home
lcdControlWrite(1<<LCD_HOME);
// set data address to 0
lcdControlWrite(1<<LCD_DDRAM | 0x00);
// load the first 8 custom characters
lcdLoadCustomChar((u08*)LcdCustomChar,0,0);
lcdLoadCustomChar((u08*)LcdCustomChar,1,1);
lcdLoadCustomChar((u08*)LcdCustomChar,2,2);
lcdLoadCustomChar((u08*)LcdCustomChar,3,3);
lcdLoadCustomChar((u08*)LcdCustomChar,4,4);
lcdLoadCustomChar((u08*)LcdCustomChar,5,5);
lcdLoadCustomChar((u08*)LcdCustomChar,6,6);
lcdLoadCustomChar((u08*)LcdCustomChar,7,7);
}
void lcdHome(void)
{
// move cursor to home
lcdControlWrite(1<<LCD_HOME);
}
void lcdClear(void)
{
// clear LCD
lcdControlWrite(1<<LCD_CLR);
}
void lcdGotoXY(u08 x, u08 y)
{
register u08 DDRAMAddr;
// remap lines into proper order
switch(y)
{
case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
}
// set data address
lcdControlWrite(1<<LCD_DDRAM | DDRAMAddr);
}
void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum)
{
register u08 i;
u08 saveDDRAMAddr;
// backup the current cursor position
saveDDRAMAddr = lcdControlRead() & 0x7F;
// multiply the character index by 8
lcdCharNum = (lcdCharNum<<3); // each character occupies 8 bytes
romCharNum = (romCharNum<<3); // each character occupies 8 bytes
// copy the 8 bytes into CG (character generator) RAM
for(i=0; i<8; i++)
{
// set CG RAM address
lcdControlWrite((1<<LCD_CGRAM) | (lcdCharNum+i));
// write character data
lcdDataWrite( pgm_read_byte(lcdCustomCharArray+romCharNum+i) );
}
// restore the previous cursor position
lcdControlWrite(1<<LCD_DDRAM | saveDDRAMAddr);
}
void lcdPrintData(char* data, u08 nBytes)
{
register u08 i;
// check to make sure we have a good pointer
if (!data) return;
// print data
for(i=0; i<nBytes; i++)
{
lcdDataWrite(data[i]);
}
}
void lcdProgressBar(u16 progress, u16 maxprogress, u08 length)
{
u08 i;
u32 pixelprogress;
u08 c;
// draw a progress bar displaying (progress / maxprogress)
// starting from the current cursor position
// with a total length of "length" characters
// ***note, LCD chars 0-5 must be programmed as the bar characters
// char 0 = empty ... char 5 = full
// total pixel length of bargraph equals length*PROGRESSPIXELS_PER_CHAR;
// pixel length of bar itself is
pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
// print exactly "length" characters
for(i=0; i<length; i++)
{
// check if this is a full block, or partial or empty
// (u16) cast is needed to avoid sign comparison warning
if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
{
// this is a partial or empty block
if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
{
// this is an empty block
// use space character?
c = 0;
}
else
{
// this is a partial block
c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
}
}
else
{
// this is a full block
c = 5;
}
// write character to display
lcdDataWrite(c);
}
}

View File

@ -1,139 +0,0 @@
/*! \file lcd.h \brief Character LCD driver for HD44780/SED1278 displays. */
//*****************************************************************************
//
// File Name : 'lcd.h'
// Title : Character LCD driver for HD44780/SED1278 displays
// (usable in mem-mapped, or I/O mode)
// Author : Pascal Stang
// Created : 11/22/2000
// Revised : 4/30/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef LCD_H
#define LCD_H
#include "global.h"
// include project-dependent configurations
#include "lcdconf.h"
// HD44780 LCD controller command set (do not modify these)
// writing:
#define LCD_CLR 0 // DB0: clear display
#define LCD_HOME 1 // DB1: return to home position
#define LCD_ENTRY_MODE 2 // DB2: set entry mode
#define LCD_ENTRY_INC 1 // DB1: increment
#define LCD_ENTRY_SHIFT 0 // DB2: shift
#define LCD_ON_CTRL 3 // DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY 2 // DB2: turn display on
#define LCD_ON_CURSOR 1 // DB1: turn cursor on
#define LCD_ON_BLINK 0 // DB0: blinking cursor
#define LCD_MOVE 4 // DB4: move cursor/display
#define LCD_MOVE_DISP 3 // DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left)
#define LCD_FUNCTION 5 // DB5: function set
#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM 6 // DB6: set CG RAM address
#define LCD_DDRAM 7 // DB7: set DD RAM address
// reading:
#define LCD_BUSY 7 // DB7: LCD is busy
// Default LCD setup
// this default setup is loaded on LCD initialization
#ifdef LCD_DATA_4BIT
#define LCD_FDEF_1 (0<<LCD_FUNCTION_8BIT)
#else
#define LCD_FDEF_1 (1<<LCD_FUNCTION_8BIT)
#endif
#define LCD_FDEF_2 (1<<LCD_FUNCTION_2LINES)
#define LCD_FUNCTION_DEFAULT ((1<<LCD_FUNCTION) | LCD_FDEF_1 | LCD_FDEF_2)
#define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC))
// custom LCD characters
extern unsigned char __attribute__ ((progmem)) LcdCustomChar[];
#define LCDCHAR_PROGRESS05 0 // 0/5 full progress block
#define LCDCHAR_PROGRESS15 1 // 1/5 full progress block
#define LCDCHAR_PROGRESS25 2 // 2/5 full progress block
#define LCDCHAR_PROGRESS35 3 // 3/5 full progress block
#define LCDCHAR_PROGRESS45 4 // 4/5 full progress block
#define LCDCHAR_PROGRESS55 5 // 5/5 full progress block
#define LCDCHAR_REWINDARROW 6 // rewind arrow
#define LCDCHAR_STOPBLOCK 7 // stop block
#define LCDCHAR_PAUSEBARS 8 // pause bars
#define LCDCHAR_FORWARDARROW 9 // fast-forward arrow
#define LCDCHAR_SCROLLUPARROW 10 // scroll up arrow
#define LCDCHAR_SCROLLDNARROW 11 // scroll down arrow
#define LCDCHAR_BLANK 12 // scroll down arrow
#define LCDCHAR_ANIPLAYICON0 13 // animated play icon frame 0
#define LCDCHAR_ANIPLAYICON1 14 // animated play icon frame 1
#define LCDCHAR_ANIPLAYICON2 15 // animated play icon frame 2
#define LCDCHAR_ANIPLAYICON3 16 // animated play icon frame 3
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR 6
// ****** Low-level functions ******
// the following functions are the only ones which deal with the CPU
// memory or port pins directly. If you decide to use a fundamentally
// different hardware interface to your LCD, only these functions need
// to be changed, after which all the high-level functions will
// work again.
// initializes I/O pins connected to LCD
void lcdInitHW(void);
// waits until LCD is not busy
void lcdBusyWait(void);
// writes a control command to the LCD
void lcdControlWrite(u08 data);
// read the control status from the LCD
u08 lcdControlRead(void);
// writes a data byte to the LCD screen at the current position
void lcdDataWrite(u08 data);
// reads the data byte on the LCD screen at the current position
u08 lcdDataRead(void);
// ****** High-levlel functions ******
// these functions provide the high-level control of the LCD
// such as clearing the display, setting cursor positions,
// displaying text and special characters
// initializes the LCD display (gets it ready for use)
void lcdInit(void);
// moves the cursor/position to Home (upper left corner)
void lcdHome(void);
// clears the LCD display
void lcdClear(void);
// moves the cursor/position to the row,col requested
// ** this may not be accurate for all displays
void lcdGotoXY(u08 row, u08 col);
// loads a special user-defined character into the LCD
// <lcdCustomCharArray> is a pointer to a ROM array containing custom characters
// <romCharNum> is the index of the character to load from lcdCustomCharArray
// <lcdCharNum> is the RAM location in the LCD (legal value: 0-7)
void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum);
// prints a series of bytes/characters to the display
void lcdPrintData(char* data, u08 nBytes);
// displays a horizontal progress bar at the current cursor location
// <progress> is the value the bargraph should indicate
// <maxprogress> is the value at the end of the bargraph
// <length> is the number of LCD characters that the bargraph should cover
void lcdProgressBar(u16 progress, u16 maxprogress, u08 length);
#endif

View File

@ -1,111 +0,0 @@
/*! \file lis3l02.c \brief ST LIS3L02 3-axis I2C Accelerometer Library. */
//*****************************************************************************
//
// File Name : 'lis3l02.c'
// Title : ST LIS3L02 3-axis I2C Accelerometer Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.10.23
// Revised : 2004.12.14
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "global.h"
#include "i2c.h"
#include "lis3l02.h"
#include "rprintf.h"
#include "timer.h"
// global variables
// Functions
u08 lis3l02Init(void)
{
// reset LIS3L02 chip
return lis3l02Reset();
}
u08 lis3l02Reset(void)
{
// turn on device and enable X,Y,Z
lis3l02WriteReg(LIS3L02_REG_CTRLREG1,
LIS3L02_CTRLREG1_XEN |
LIS3L02_CTRLREG1_YEN |
LIS3L02_CTRLREG1_ZEN |
LIS3L02_CTRLREG1_PD0);
// scale and justification options
lis3l02WriteReg(LIS3L02_REG_CTRLREG2,
LIS3L02_CTRLREG2_BOOT |
LIS3L02_CTRLREG2_DAS );
return 0;
}
u08 lis3l02ReadReg(u08 reg)
{
u08 data;
u08 i2cStat;
// set register
i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 1, &reg);
if(i2cStat == I2C_ERROR_NODEV)
{
rprintf("No I2C Device\r\n");
return i2cStat;
}
// read register
i2cStat = i2cMasterReceiveNI(LIS3L02_I2C_ADDR, 1, &data);
//rprintf("READ: Reg=0x%x Data=0x%x\r\n", reg, data);
return data;
}
u08 lis3l02WriteReg(u08 reg, u08 data)
{
u08 packet[2];
u08 i2cStat;
// prepare packet
packet[0] = reg;
packet[1] = data;
// write register
i2cStat = i2cMasterSendNI(LIS3L02_I2C_ADDR, 2, packet);
if(i2cStat == I2C_ERROR_NODEV)
{
rprintf("No I2C Device\r\n");
return i2cStat;
}
//rprintf("WRITE: Reg=0x%x Data=0x%x\r\n", reg, data);
return (i2cStat == I2C_OK);
}
s16 lis3l02GetAccel(u08 chxyz)
{
s16 value;
value = lis3l02ReadReg(LIS3L02_REG_OUTXL + (chxyz<<1));
value |= lis3l02ReadReg(LIS3L02_REG_OUTXH + (chxyz<<1))<<8;
return value;
}

View File

@ -1,113 +0,0 @@
/*! \file lis3l02.h \brief ST LIS3L02 3-axis I2C Accelerometer Library. */
//*****************************************************************************
//
// File Name : 'lis3l02.h'
// Title : ST LIS3L02 3-axis I2C Accelerometer Library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.10.23
// Revised : 2004.12.14
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef LIS3L02_H
#define LIS3L02_H
#include "global.h"
// constants/macros/typdefs
#define LIS3L02_I2C_ADDR 0x3A //< Base I2C address of LIS3L02 device
// LIS3L02 register address defines
#define LIS3L02_REG_OFFSETX 0x16 //< LIS3L02 X-axis digital offset trim
#define LIS3L02_REG_OFFSETY 0x17 //< LIS3L02 Y-axis digital offset trim
#define LIS3L02_REG_OFFSETZ 0x18 //< LIS3L02 Z-axis digital offset trim
#define LIS3L02_REG_GAINX 0x19 //< LIS3L02 X-axis digital gain trim
#define LIS3L02_REG_GAINY 0x1A //< LIS3L02 Y-axis digital gain trim
#define LIS3L02_REG_GAINZ 0x1B //< LIS3L02 Z-axis digital gain trim
#define LIS3L02_REG_CTRLREG1 0x20 //< LIS3L02 interface/operation control
#define LIS3L02_REG_CTRLREG2 0x21 //< LIS3L02 interface/operation control
#define LIS3L02_REG_WAKEUPCFG 0x23 //< LIS3L02 interrupt/wakeup config
#define LIS3L02_REG_WAKEUPSRC 0x24 //< LIS3L02 interrupt/wakeup source indicator
#define LIS3L02_REG_WAKEUPACK 0x25 //< LIS3L02 wakeup source clear
#define LIS3L02_REG_STATUS 0x27 //< LIS3L02 Accelerometer Status
#define LIS3L02_REG_OUTXL 0x28 //< LIS3L02 Accelerometer X Output Low-byte
#define LIS3L02_REG_OUTXH 0x29 //< LIS3L02 Accelerometer X Output High-byte
#define LIS3L02_REG_OUTYL 0x2A //< LIS3L02 Accelerometer Y Output Low-byte
#define LIS3L02_REG_OUTYH 0x2B //< LIS3L02 Accelerometer Y Output High-byte
#define LIS3L02_REG_OUTZL 0x2C //< LIS3L02 Accelerometer Z Output Low-byte
#define LIS3L02_REG_OUTZH 0x2D //< LIS3L02 Accelerometer Z Output High-byte
#define LIS3L02_REG_THSL 0x2E //< LIS3L02 Accelerometer Threshold Low-byte
#define LIS3L02_REG_THSH 0x2F //< LIS3L02 Accelerometer Threshold High-byte
#define LIS3L02_REG_MULTIREAD 0x80 //< LIS3L02 Mutliple Read Bit
// LIS3L02 control register 1 bit defines
#define LIS3L02_CTRLREG1_XEN 0x01 //< LIS3L02 CtrlReg1 X-axis Enable
#define LIS3L02_CTRLREG1_YEN 0x02 //< LIS3L02 CtrlReg1 Y-axis Enable
#define LIS3L02_CTRLREG1_ZEN 0x04 //< LIS3L02 CtrlReg1 Z-axis Enable
#define LIS3L02_CTRLREG1_ST 0x08 //< LIS3L02 CtrlReg1 Self-Test Enable
#define LIS3L02_CTRLREG1_DF0 0x10 //< LIS3L02 CtrlReg1 Decimation Factor 0
#define LIS3L02_CTRLREG1_DF1 0x20 //< LIS3L02 CtrlReg1 Decimation Factor 0
#define LIS3L02_CTRLREG1_PD0 0x40 //< LIS3L02 CtrlReg1 Power-down Control 0
#define LIS3L02_CTRLREG1_PD1 0x80 //< LIS3L02 CtrlReg1 Power-down Control 1
// LIS3L02 control register 2 bit defines
#define LIS3L02_CTRLREG2_DAS 0x01 //< LIS3L02 CtrlReg2 Data Alignment Selection
#define LIS3L02_CTRLREG2_SIM 0x02 //< LIS3L02 CtrlReg2 SPI Mode Select
#define LIS3L02_CTRLREG2_DRDY 0x04 //< LIS3L02 CtrlReg2 Enable Data-Ready generation
#define LIS3L02_CTRLREG2_IEN 0x08 //< LIS3L02 CtrlReg2 Interrupt Enable
#define LIS3L02_CTRLREG2_BOOT 0x10 //< LIS3L02 CtrlReg2 Reboot from memory
#define LIS3L02_CTRLREG2_FS 0x80 //< LIS3L02 CtrlReg2 Full-scale Select (0=2g, 1=6g)
// LIS3L02 WAKEUPCFG register bit defines
#define LIS3L02_WAKEUPCFG_MXL 0x01 //< LIS3L02 WAKEUPCFG Mask X Low Interrupt
#define LIS3L02_WAKEUPCFG_MXH 0x02 //< LIS3L02 WAKEUPCFG Mask X High Interrupt
#define LIS3L02_WAKEUPCFG_MYL 0x04 //< LIS3L02 WAKEUPCFG Mask Y Low Interrupt
#define LIS3L02_WAKEUPCFG_MYH 0x08 //< LIS3L02 WAKEUPCFG Mask Y High Interrupt
#define LIS3L02_WAKEUPCFG_MZL 0x10 //< LIS3L02 WAKEUPCFG Mask Z Low Interrupt
#define LIS3L02_WAKEUPCFG_MZH 0x20 //< LIS3L02 WAKEUPCFG Mask Z High Interrupt
#define LIS3L02_WAKEUPCFG_LIR 0x40 //< LIS3L02 WAKEUPCFG Latch Intr Request
// LIS3L02 WAKEUPSRC register bit defines
#define LIS3L02_WAKEUPSRC_XL 0x01 //< LIS3L02 WAKEUPSRC X Low Interrupt
#define LIS3L02_WAKEUPSRC_XH 0x02 //< LIS3L02 WAKEUPSRC X High Interrupt
#define LIS3L02_WAKEUPSRC_YL 0x04 //< LIS3L02 WAKEUPSRC Y Low Interrupt
#define LIS3L02_WAKEUPSRC_YH 0x08 //< LIS3L02 WAKEUPSRC Y High Interrupt
#define LIS3L02_WAKEUPSRC_ZL 0x10 //< LIS3L02 WAKEUPSRC Z Low Interrupt
#define LIS3L02_WAKEUPSRC_ZH 0x20 //< LIS3L02 WAKEUPSRC Z High Interrupt
#define LIS3L02_WAKEUPSRC_IA 0x40 //< LIS3L02 WAKEUPSRC Interrupt Active
// LIS3L02 WAKEUPSRC register bit defines
#define LIS3L02_STATUS_XDA 0x01 //< LIS3L02 STATUS X New Data Available
#define LIS3L02_STATUS_YDA 0x02 //< LIS3L02 STATUS Y New Data Available
#define LIS3L02_STATUS_ZDA 0x04 //< LIS3L02 STATUS Z New Data Available
#define LIS3L02_STATUS_ZYXDA 0x08 //< LIS3L02 STATUS XYZ New Data Available
#define LIS3L02_STATUS_XOR 0x10 //< LIS3L02 STATUS X-axis Data Overrun
#define LIS3L02_STATUS_YOR 0x20 //< LIS3L02 STATUS Y-axis Data Overrun
#define LIS3L02_STATUS_ZOR 0x40 //< LIS3L02 STATUS Z-axis Data Overrun
#define LIS3L02_STATUS_ZYXOR 0x80 //< LIS3L02 STATUS XYZ-axis Data Overrun
// functions
//! Initialize the LIS3L02 chip
// returns:
// 0 if successful
// non-zero if unsuccessful (chip not present)
u08 lis3l02Init(void);
u08 lis3l02Reset(void);
u08 lis3l02ReadReg(u08 reg);
u08 lis3l02WriteReg(u08 reg, u08 data);
s16 lis3l02GetAccel(u08 chxyz);
#endif

View File

@ -1,113 +0,0 @@
#----------------------------------------------------------------------------------
# ARM-GCC standard Makefile
# This makefile is to be used by including it from a project-specific makefile
# which defines the source files and compiler/linker options
#
# Written by Pascal Stang
# Based on Volker Oth's AVR makefiles of jan.2000
# ---------------------------------------------------------------------------------
###### BLOCK 1) define some variables based on the AVR base path in $(AVR) #######
CC = avr-gcc
AS = avr-gcc -x assembler-with-cpp
RM = rm -f
RN = mv
CP = cp
BIN = avr-objcopy
SIZE = avr-size
INCDIR = .
# LIBDIR = $(AVR)/avr/lib
# SHELL = $(AVR)/bin/sh.exe
###### BLOCK 2) output format can be srec, ihex (avrobj is always created) #######
FORMAT = ihex
###### BLOCK 3) define all project specific object files ######
SRC += $(addprefix $(AVRLIB)/,$(AVRLIB_SRC))
OBJ = $(ASRC:.s=.o) $(SRC:.c=.o)
CPFLAGS += -mmcu=$(MCU)
ASFLAGS += -mmcu=$(MCU)
LDFLAGS += -mmcu=$(MCU)
###### BLOCK 4) this defines the aims of the make process ######
#all: $(TRG).obj $(TRG).elf $(TRG).hex $(TRG).cof $(TRG).eep $(TRG).ok
all: $(TRG).elf $(TRG).cof $(TRG).hex $(TRG).eep $(TRG).ok
###### BLOCK 5) compile: instructions to create assembler and/or object files from C source ######
%.o : %.c
$(CC) -c $(CPFLAGS) -I$(INCDIR) $< -o $@
%.s : %.c
$(CC) -S $(CPFLAGS) -I$(INCDIR) $< -o $@
###### BLOCK 6) assemble: instructions to create object file from assembler files ######
%.o : %.s
$(AS) -c $(ASFLAGS) -I$(INCDIR) $< -o $@
###### BLOCK 7) link: instructions to create elf output file from object files ######
%.elf: $(OBJ)
$(CC) $(OBJ) $(LIB) $(LDFLAGS) -o $@
###### BLOCK 8) create avrobj file from elf output file ######
#%.obj: %.elf
# $(BIN) -O avrobj -R .eeprom $< $@
###### BLOCK 9) create bin (.hex and .eep) files from elf output file ######
%.hex: %.elf
$(BIN) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
$(BIN) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
%.cof: %.elf
$(BIN) --debugging -O coff-ext-avr \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000 \
$< $@
###### BLOCK 10) If all other steps compile ok then echo "Errors: none" ######
%ok:
$(SIZE) $(TRG).elf
@echo "Errors: none"
###### BLOCK 11) make instruction to delete created files ######
clean:
$(RM) $(OBJ)
$(RM) $(SRC:.c=.s)
$(RM) $(SRC:.c=.lst)
$(RM) $(TRG).map
$(RM) $(TRG).elf
$(RM) $(TRG).cof
$(RM) $(TRG).obj
$(RM) $(TRG).a90
$(RM) $(TRG).hex
$(RM) $(TRG).sym
$(RM) $(TRG).eep
$(RM) $(TRG).hex
$(RM) *.bak
$(RM) *.log
@echo "Errors: none"
size:
$(SIZE) $(TRG).elf

View File

@ -1,111 +0,0 @@
#----------------------------------------------------------------------------------
# GCC-AVR standard Makefile part 3
# Based on Volker Oth's makefiles of jan.2000
# Modified and merged by AVRfreaks.net for smoother integration with AVR Studio,
# and easier comprehension for the average user (nov.2001). Minor errors corrected.
# ---------------------------------------------------------------------------------
###### BLOCK 1) define some variables based on the AVR base path in $(AVR) #######
CC = avr-gcc
AS = avr-gcc -x assembler-with-cpp
RM = rm -f
RN = mv
CP = cp
BIN = avr-objcopy
SIZE = avr-size
INCDIR = .
# LIBDIR = $(AVR)/avr/lib
# SHELL = $(AVR)/bin/sh.exe
###### BLOCK 2) output format can be srec, ihex (avrobj is always created) #######
FORMAT = ihex
###### BLOCK 3) define all project specific object files ######
SRC += $(AVRLIBSRC)
OBJ = $(ASRC:.s=.o) $(SRC:.c=.o)
CPFLAGS += -mmcu=$(MCU)
ASFLAGS += -mmcu=$(MCU)
LDFLAGS += -mmcu=$(MCU)
###### BLOCK 4) this defines the aims of the make process ######
#all: $(TRG).obj $(TRG).elf $(TRG).hex $(TRG).cof $(TRG).eep $(TRG).ok
all: $(TRG).elf $(TRG).cof $(TRG).hex $(TRG).eep $(TRG).ok
###### BLOCK 5) compile: instructions to create assembler and/or object files from C source ######
%.o : %.c
$(CC) -c $(CPFLAGS) -I$(INCDIR) $< -o $@
%.s : %.c
$(CC) -S $(CPFLAGS) -I$(INCDIR) $< -o $@
###### BLOCK 6) assemble: instructions to create object file from assembler files ######
%.o : %.s
$(AS) -c $(ASFLAGS) -I$(INCDIR) $< -o $@
###### BLOCK 7) link: instructions to create elf output file from object files ######
%.elf: $(OBJ)
$(CC) $(OBJ) $(LIB) $(LDFLAGS) -o $@
###### BLOCK 8) create avrobj file from elf output file ######
#%.obj: %.elf
# $(BIN) -O avrobj -R .eeprom $< $@
###### BLOCK 9) create bin (.hex and .eep) files from elf output file ######
%.hex: %.elf
$(BIN) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
$(BIN) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
%.cof: %.elf
$(BIN) --debugging -O coff-ext-avr \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000 \
$< $@
###### BLOCK 10) If all other steps compile ok then echo "Errors: none" ######
%ok:
$(SIZE) $(TRG).elf
@echo "Errors: none"
###### BLOCK 11) make instruction to delete created files ######
clean:
$(RM) $(OBJ)
$(RM) $(SRC:.c=.s)
$(RM) $(SRC:.c=.lst)
$(RM) $(TRG).map
$(RM) $(TRG).elf
$(RM) $(TRG).cof
$(RM) $(TRG).obj
$(RM) $(TRG).a90
$(RM) $(TRG).hex
$(RM) $(TRG).sym
$(RM) $(TRG).eep
$(RM) $(TRG).hex
$(RM) *.bak
$(RM) *.log
@echo "Errors: none"
size:
$(SIZE) $(TRG).elf

View File

@ -1,26 +0,0 @@
The "avrproj_make" file in this directory is an important part of the
compiling process for all AVRLib example code. Unless you are familiar with
writing your own makefiles, it is highly suggested that you use this file
to help compile your own code projects too.
------------------------------------------------------------------------------
To make "avrproj_make" work, you must have the following two environment
variables defined with appropriate values:
AVR = [path to WinAVR/AVR-GCC install directory]
AVRLIB = [path to AVRLib install directory]
For example, if you installed WinAVR in C:\WinAVR, then you should set:
AVR = c:\WinAVR
If you installed/unzipped AVRLib in c:\code\avr\avrlib, then set:
AVRLib = c:\code\avr\avrlib
------------------------------------------------------------------------------
If you are unsure how to set environment variables on your system, check the
installation guides on hubbard.engr.scu.edu/embedded or consult the web.

View File

@ -1,175 +0,0 @@
/*! \file megaio.c \brief MegaIO Control/Access function library. */
//*****************************************************************************
//
// File Name : 'megaio.c'
// Title : MegaIO Control/Access function library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 5/18/2004
// Revised : 5/18/2004
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "buffer.h" // include buffer support
#include "i2c.h" // include I2C functions
#include "megaio/megaioreg.h" // include MegaIO register definitions
#include "megaio.h"
// MegaIO local receive buffer size
#define MEGAIO_UART_RX_BUFFER_SIZE 0x80
// MegaIO local receive buffer data array
static char megaioUartRxData[MEGAIO_UART_RX_BUFFER_SIZE];
// MegaIO local receive buffer
cBuffer megaioUartRxBuffer;
//! initialize the MegaIO interface
u08 megaioInit(void)
{
// initialize the UART receive buffer
bufferInit(&megaioUartRxBuffer, megaioUartRxData, MEGAIO_UART_RX_BUFFER_SIZE);
// initialize i2c interface
i2cInit();
i2cSetBitrate(30);
// check for presence of megaio chip
if( megaioReadReg(MEGAIOREG_IDSTRING, 1) == 'M' )
{
// megaio responded correctly
// initialization succeeded
return TRUE;
}
else
{
// megaio responded incorrectly
// initialization failed
return FALSE;
}
}
//! write an 8-32 bit number to a MegaIO register
void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data)
{
u08 packet[5];
// construct I2c data packet
// first byte is register address
// following bytes are the data that will be written to that register
packet[0] = regnum;
packet[1] = data;
packet[2] = data>>8;
packet[3] = data>>16;
packet[4] = data>>24;
// send 2 bytes (register and data) to MegaIO
i2cMasterSend(MEGAIO_I2C_ADDR, 1+nbytes, packet);
}
//! read an 8-32 bit number from a MegaIO register
unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes)
{
unsigned long data = 0;
// first select the register by writing 1 byte (register)
i2cMasterSend(MEGAIO_I2C_ADDR, 1, &regnum);
// then read n byte(s) from the selected MegaIO register
i2cMasterReceive(MEGAIO_I2C_ADDR, nbytes, (u08*)&data);
// return the results
return data;
}
//! set the baudrate of the megaio serial port
void megaioSetBaudRate(u32 baudrate)
{
megaioWriteReg(MEGAIOREG_UARTBAUD, 4, baudrate);
}
//! send a byte out the megaio serial port
void megaioSendByte(u08 data)
{
megaioWriteReg(MEGAIOREG_UARTDATA, 1, data);
}
//! get a byte from the megaio serial port
int megaioGetByte(void)
{
u08 data;
// check the number of bytes in the megaio receive buffer
if( megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1) )
{
// one or more bytes are available
// get first byte
data = megaioReadReg(MEGAIOREG_UARTDATA, 1);
return data;
}
else
{
// no bytes were available
// (no bytes have arrived and are waiting to be read)
return -1;
}
}
//! returns the receive buffer structure
cBuffer* megaioGetRxBuffer(void)
{
u08 nbytes;
// get the number of bytes waiting in the MegaIO buffer
nbytes = megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1);
// get all available bytes from the MegaIO chip
// and add them to the receive buffer
while(megaioReadReg(MEGAIOREG_UARTRXBUFBYTES, 1))
{
bufferAddToEnd(&megaioUartRxBuffer, megaioReadReg(MEGAIOREG_UARTDATA, 1));
nbytes--;
}
// return rx buffer pointer
return &megaioUartRxBuffer;
}
//! turn on megaio PWM and set for bitRes resolution
void megaioPWMInit(u08 bitRes)
{
megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, bitRes);
}
//! turn off megaio PWM
void megaioPWMOff(void)
{
megaioWriteReg(MEGAIOREG_PWM1CTRL, 1, 0);
}
//! set megaio PWM1A duty cycle
void megaioPWMASet(u16 pwmDuty)
{
megaioWriteReg(MEGAIOREG_PWM1ADUTY, 2, pwmDuty);
}
//! set megaio PWM1B duty cycle
void megaioPWMBSet(u16 pwmDuty)
{
megaioWriteReg(MEGAIOREG_PWM1BDUTY, 2, pwmDuty);
}
//! set megaio prescaler division rate
void megaioSetPrescaler(u08 prescaleDiv)
{
megaioWriteReg(MEGAIOREG_PWM1FREQ, 1, prescaleDiv);
}
//! do A/D conversion on channel [ch] and return result
u16 megaioA2DConvert(u08 ch)
{
// set channel
megaioWriteReg(MEGAIOREG_ADCCHSEL, 1, ch);
// start single conversion
megaioWriteReg(MEGAIOREG_ADCCTRL, 1, 0x01);
// wait for conversion to be complete
while( megaioReadReg(MEGAIOREG_ADCCTRL, 1) );
// get result and return it
return megaioReadReg(MEGAIOREG_ADCRESULT, 2);
}

View File

@ -1,57 +0,0 @@
/*! \file megaio.h \brief MegaIO Control/Access function library. */
//*****************************************************************************
//
// File Name : 'megaio.h'
// Title : MegaIO Control/Access function library
// Author : Pascal Stang - Copyright (C) 2004
// Created : 5/18/2004
// Revised : 5/18/2004
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef MEGAIO_H
#define MEGAIO_H
#include "megaio/megaioreg.h" // include MegaIO register definitions
// defines
// function prototypes
//! initialize the MegaIO interface
u08 megaioInit(void);
//! write an 8-32 bit number to a MegaIO register
void megaioWriteReg(unsigned char regnum, unsigned char nbytes, unsigned long data);
//! read an 8-32 bit number from a MegaIO register
unsigned long megaioReadReg(unsigned char regnum, unsigned char nbytes);
//! set the baudrate of the MegaIO serial port
void megaioSetBaudRate(u32 baudrate);
//! send a byte out the MegaIO serial port
void megaioSendByte(u08 data);
//! get a byte from the MegaIO serial port
int megaioGetByte(void);
//! get a complete receive buffer with data from MegaIO serial port
cBuffer* megaioGetRxBuffer(void);
//! turn on MegaIO PWM and set for bitRes resolution
void megaioPWMInit(u08 bitRes);
//! turn off MegaIO PWM
void megaioPWMOff(void);
//! set MegaIO PWM1A duty cycle
void megaioPWMASet(u16 pwmDuty);
//! set MegaIO PWM1B duty cycle
void megaioPWMBSet(u16 pwmDuty);
//! set MegaIO prescaler division rate
void megaioSetPrescaler(u08 prescaleDiv);
//! do A/D conversion on channel [ch] and return result
u16 megaioA2DConvert(u08 ch);
#endif

View File

@ -1,88 +0,0 @@
/*! \file megaioreg.h \brief MegaIO register definitions. */
//*****************************************************************************
//
// File Name : 'megaioreg.h'
// Title : MegaIO register definitions
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.07.16
// Revised : 2003.07.17
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef MEGAIOREG_H
#define MEGAIOREG_H
// define MEGAIO I2C address
#define MEGAIO_I2C_ADDR 0x4C
// define MEGAIO registers
// General Registers
#define MEGAIOREG_IDSTRING 0x00
// UART Registers
#define MEGAIOREG_UARTDATA 0x10
#define MEGAIOREG_UARTBAUD 0x14
#define MEGAIOREG_UARTBAUDSEL 0x15
#define MEGAIOREG_UARTRXBUFBYTES 0x18
#define MEGAIOREG_UARTTXBUFBYTES 0x19
// PWM Registers
#define MEGAIOREG_PWM1CTRL 0x20
#define MEGAIOREG_PWM1FREQ 0x21
#define MEGAIOREG_PWM1ADUTY 0x24
#define MEGAIOREG_PWM1BDUTY 0x25
// A/D Converter Registers
#define MEGAIOREG_ADCCTRL 0x30
#define MEGAIOREG_ADCCHSEL 0x31
#define MEGAIOREG_ADCRESULT 0x32
// PORT Access Registers
#define MEGAIOREG_PORTA 0x40
#define MEGAIOREG_DDRA 0x41
#define MEGAIOREG_PINA 0x42
#define MEGAIOREG_PORTB 0x43
#define MEGAIOREG_DDRB 0x44
#define MEGAIOREG_PINB 0x45
#define MEGAIOREG_PORTC 0x46
#define MEGAIOREG_DDRC 0x47
#define MEGAIOREG_PINC 0x48
#define MEGAIOREG_PORTD 0x49
#define MEGAIOREG_DDRD 0x4A
#define MEGAIOREG_PIND 0x4B
#define MEGAIOREG_PORTE 0x4C
#define MEGAIOREG_DDRE 0x4D
#define MEGAIOREG_PINE 0x4E
#define MEGAIOREG_PORTF 0x4F
#define MEGAIOREG_DDRF 0x50
#define MEGAIOREG_PINF 0x51
// Direct Access Registers
#define MEGAIOREG_DIRECTIO 0x80
#define MEGAIOREG_DIRECTMEM 0x81
// define MEGAIO register values
#define UARTBAUDSEL_300 0x00
#define UARTBAUDSEL_600 0x01
#define UARTBAUDSEL_1200 0x02
#define UARTBAUDSEL_2400 0x03
#define UARTBAUDSEL_4800 0x04
#define UARTBAUDSEL_9600 0x05
#define UARTBAUDSEL_19200 0x06
#define UARTBAUDSEL_38400 0x07
#define UARTBAUDSEL_115200 0x08
#define PWM1FREQ_STOP 0x00
#define PWM1FREQ_MAX 0x01
#define PWM1FREQ_DIV8 0x02
#define PWM1FREQ_DIV64 0x03
#define PWM1FREQ_DIV256 0x04
#define PWM1FREQ_DIV1024 0x05
#endif

View File

@ -1,211 +0,0 @@
/*! \file mmc.c \brief MultiMedia and SD Flash Card Interface. */
//*****************************************************************************
//
// File Name : 'mmc.c'
// Title : MultiMedia and SD Flash Card Interface
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.09.22
// Revised : 2004.09.22
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
//----- Include Files ---------------------------------------------------------
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
#include <avr/signal.h> // include "signal" names (interrupt names)
#include <avr/interrupt.h> // include interrupt support
#include "global.h" // include our global settings
#include "spi.h" // include spi bus support
#include "rprintf.h"
#include "mmc.h"
// include project-specific hardware configuration
#include "mmcconf.h"
// Global variables
// Functions
void mmcInit(void)
{
// initialize SPI interface
spiInit();
// release chip select
sbi(MMC_CS_DDR, MMC_CS_PIN);
sbi(MMC_CS_PORT,MMC_CS_PIN);
}
u08 mmcReset(void)
{
u08 retry;
u08 r1=0;
retry = 0;
do
{
// send dummy bytes with CS high before accessing
spiTransferByte(0xFF);
spiTransferByte(0xFF);
spiTransferByte(0xFF);
spiTransferByte(0xFF);
// resetting card, go to SPI mode
r1 = mmcSendCommand(MMC_GO_IDLE_STATE, 0);
#ifdef MMC_DEBUG
rprintf("MMC_GO_IDLE_STATE: R1=0x%x\r\n", r1);
#endif
// do retry counter
retry++;
if(retry>10) return -1;
} while(r1 != 0x01);
// TODO: check card parameters for voltage compliance
// before issuing initialize command
retry = 0;
do
{
// initializing card for operation
r1 = mmcSendCommand(MMC_SEND_OP_COND, 0);
#ifdef MMC_DEBUG
rprintf("MMC_SEND_OP_COND: R1=0x%x\r\n", r1);
#endif
// do retry counter
retry++;
if(retry>100) return -1;
} while(r1);
// turn off CRC checking to simplify communication
r1 = mmcSendCommand(MMC_CRC_ON_OFF, 0);
#ifdef MMC_DEBUG
rprintf("MMC_CRC_ON_OFF: R1=0x%x\r\n", r1);
#endif
// set block length to 512 bytes
r1 = mmcSendCommand(MMC_SET_BLOCKLEN, 512);
#ifdef MMC_DEBUG
rprintf("MMC_SET_BLOCKLEN: R1=0x%x\r\n", r1);
#endif
// return success
return 0;
}
u08 mmcSendCommand(u08 cmd, u32 arg)
{
u08 r1;
// assert chip select
cbi(MMC_CS_PORT,MMC_CS_PIN);
// issue the command
r1 = mmcCommand(cmd, arg);
// release chip select
sbi(MMC_CS_PORT,MMC_CS_PIN);
return r1;
}
u08 mmcRead(u32 sector, u08* buffer)
{
u08 r1;
u16 i;
// assert chip select
cbi(MMC_CS_PORT,MMC_CS_PIN);
// issue command
r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9);
#ifdef MMC_DEBUG
rprintf("MMC Read Block R1=0x%x\r\n", r1);
#endif
// check for valid response
if(r1 != 0x00)
return r1;
// wait for block start
while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ);
// read in data
for(i=0; i<0x200; i++)
{
*buffer++ = spiTransferByte(0xFF);
}
// read 16-bit CRC
spiTransferByte(0xFF);
spiTransferByte(0xFF);
// release chip select
sbi(MMC_CS_PORT,MMC_CS_PIN);
// return success
return 0;
}
u08 mmcWrite(u32 sector, u08* buffer)
{
u08 r1;
u16 i;
// assert chip select
cbi(MMC_CS_PORT,MMC_CS_PIN);
// issue command
r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9);
#ifdef MMC_DEBUG
rprintf("MMC Write Block R1=0x%x\r\n", r1);
#endif
// check for valid response
if(r1 != 0x00)
return r1;
// send dummy
spiTransferByte(0xFF);
// send data start token
spiTransferByte(MMC_STARTBLOCK_WRITE);
// write data
for(i=0; i<0x200; i++)
{
spiTransferByte(*buffer++);
}
// write 16-bit CRC (dummy values)
spiTransferByte(0xFF);
spiTransferByte(0xFF);
// read data response token
r1 = spiTransferByte(0xFF);
if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT)
return r1;
#ifdef MMC_DEBUG
rprintf("Data Response Token=0x%x\r\n", r1);
#endif
// wait until card not busy
while(!spiTransferByte(0xFF));
// release chip select
sbi(MMC_CS_PORT,MMC_CS_PIN);
// return success
return 0;
}
u08 mmcCommand(u08 cmd, u32 arg)
{
u08 r1;
u08 retry=0;
// send command
spiTransferByte(cmd | 0x40);
spiTransferByte(arg>>24);
spiTransferByte(arg>>16);
spiTransferByte(arg>>8);
spiTransferByte(arg);
spiTransferByte(0x95); // crc valid only for MMC_GO_IDLE_STATE
// end command
// wait for response
// if more than 8 retries, card has timed-out
// return the received 0xFF
while((r1 = spiTransferByte(0xFF)) == 0xFF)
if(retry++ > 8) break;
// return response
return r1;
}

View File

@ -1,125 +0,0 @@
/*! \file mmc.h \brief MultiMedia and SD Flash Card Interface. */
//*****************************************************************************
//
// File Name : 'mmc.h'
// Title : MultiMedia and SD Flash Card Interface
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.09.22
// Revised : 2004.09.22
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Description : This library offers some simple function which can be used
// to read and write data on a MultiMedia or SecureDigital (SD) Flash
// Card. Although MM and SD Cards are designed to operate with their own
// special bus wiring and protocols, both types of cards also provide a
// simple SPI-like interface mode which is exceptionally useful when
// attempting to use the cards in embedded systems.
//
// To work with this library, the card must be wired to the SPI port of
// the Atmel microcontroller as described below.
// _________________
// / 1 2 3 4 5 6 78 | <- view of MMC/SD card looking at contacts
// / 9 | Pins 8 and 9 are present only on SD cards
// | MMC/SD Card |
// /\/\/\/\/\/\/\/\/\/
//
// 1 - CS (chip select) - wire to any available I/O pin(*)
// 2 - DIN (data in, card<-host) - wire to SPI MOSI pin
// 3 - VSS (ground) - wire to ground
// 4 - VDD (power, 3.3V only?) - wire to power (MIGHT BE 3.3V ONLY!)
// 5 - SCLK (data clock) - wire to SPI SCK pin
// 6 - VSS (ground) - wire to ground
// 7 - DOUT (data out, card->host) - wire to SPI MISO pin
//
// (*) you must define this chip select I/O pin in mmcconf.h
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef MMC_H
#define MMC_H
#include "global.h"
// constants/macros/typdefs
// MMC commands (taken from sandisk MMC reference)
#define MMC_GO_IDLE_STATE 0
#define MMC_SEND_OP_COND 1
#define MMC_SEND_CSD 9
#define MMC_SEND_CID 10
#define MMC_SEND_STATUS 13
#define MMC_SET_BLOCKLEN 16
#define MMC_READ_SINGLE_BLOCK 17
#define MMC_WRITE_BLOCK 24
#define MMC_PROGRAM_CSD 27
#define MMC_SET_WRITE_PROT 28
#define MMC_CLR_WRITE_PROT 29
#define MMC_SEND_WRITE_PROT 30
#define MMC_TAG_SECTOR_START 32
#define MMC_TAG_SECTOR_END 33
#define MMC_UNTAG_SECTOR 34
#define MMC_TAG_ERASE_GROUP_START 35
#define MMC_TAG_ERARE_GROUP_END 36
#define MMC_UNTAG_ERASE_GROUP 37
#define MMC_ERASE 38
#define MMC_CRC_ON_OFF 59
// R1 Response bit-defines
#define MMC_R1_BUSY 0x80
#define MMC_R1_PARAMETER 0x40
#define MMC_R1_ADDRESS 0x20
#define MMC_R1_ERASE_SEQ 0x10
#define MMC_R1_COM_CRC 0x08
#define MMC_R1_ILLEGAL_COM 0x04
#define MMC_R1_ERASE_RESET 0x02
#define MMC_R1_IDLE_STATE 0x01
// Data Start tokens
#define MMC_STARTBLOCK_READ 0xFE
#define MMC_STARTBLOCK_WRITE 0xFE
#define MMC_STARTBLOCK_MWRITE 0xFC
// Data Stop tokens
#define MMC_STOPTRAN_WRITE 0xFD
// Data Error Token values
#define MMC_DE_MASK 0x1F
#define MMC_DE_ERROR 0x01
#define MMC_DE_CC_ERROR 0x02
#define MMC_DE_ECC_FAIL 0x04
#define MMC_DE_OUT_OF_RANGE 0x04
#define MMC_DE_CARD_LOCKED 0x04
// Data Response Token values
#define MMC_DR_MASK 0x1F
#define MMC_DR_ACCEPT 0x05
#define MMC_DR_REJECT_CRC 0x0B
#define MMC_DR_REJECT_WRITE_ERROR 0x0D
// functions
//! Initialize hardware interface
void mmcInit(void);
//! Initialize the card and prepare it for use
// returns zero if successful
u08 mmcReset(void);
//! Send card an MMC command
// returns R1 result code
u08 mmcSendCommand(u08 cmd, u32 arg);
//! Read 512-byte sector from card to buffer
// returns zero if successful
u08 mmcRead(u32 sector, u08* buffer);
//! Write 512-byte sector from buffer to card
// returns zero if successful
u08 mmcWrite(u32 sector, u08* buffer);
//! internal command function
u08 mmcCommand(u08 cmd, u32 arg);
#endif

View File

@ -1,260 +0,0 @@
/*! \file nmea.c \brief NMEA protocol function library. */
//*****************************************************************************
//
// File Name : 'nmea.c'
// Title : NMEA protocol function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 2002.08.27
// Revised : 2002.08.27
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "buffer.h"
#include "rprintf.h"
#include "gps.h"
#include "nmea.h"
// Program ROM constants
// Global variables
extern GpsInfoType GpsInfo;
u08 NmeaPacket[NMEA_BUFFERSIZE];
void nmeaInit(void)
{
}
u08* nmeaGetPacketBuffer(void)
{
return NmeaPacket;
}
u08 nmeaProcess(cBuffer* rxBuffer)
{
u08 foundpacket = NMEA_NODATA;
u08 startFlag = FALSE;
//u08 data;
u16 i,j;
// process the receive buffer
// go through buffer looking for packets
while(rxBuffer->datalength)
{
// look for a start of NMEA packet
if(bufferGetAtIndex(rxBuffer,0) == '$')
{
// found start
startFlag = TRUE;
// when start is found, we leave it intact in the receive buffer
// in case the full NMEA string is not completely received. The
// start will be detected in the next nmeaProcess iteration.
// done looking for start
break;
}
else
bufferGetFromFront(rxBuffer);
}
// if we detected a start, look for end of packet
if(startFlag)
{
for(i=1; i<(rxBuffer->datalength)-1; i++)
{
// check for end of NMEA packet <CR><LF>
if((bufferGetAtIndex(rxBuffer,i) == '\r') && (bufferGetAtIndex(rxBuffer,i+1) == '\n'))
{
// have a packet end
// dump initial '$'
bufferGetFromFront(rxBuffer);
// copy packet to NmeaPacket
for(j=0; j<(i-1); j++)
{
// although NMEA strings should be 80 characters or less,
// receive buffer errors can generate erroneous packets.
// Protect against packet buffer overflow
if(j<(NMEA_BUFFERSIZE-1))
NmeaPacket[j] = bufferGetFromFront(rxBuffer);
else
bufferGetFromFront(rxBuffer);
}
// null terminate it
NmeaPacket[j] = 0;
// dump <CR><LF> from rxBuffer
bufferGetFromFront(rxBuffer);
bufferGetFromFront(rxBuffer);
#ifdef NMEA_DEBUG_PKT
rprintf("Rx NMEA packet type: ");
rprintfStrLen(NmeaPacket, 0, 5);
rprintfStrLen(NmeaPacket, 5, (i-1)-5);
rprintfCRLF();
#endif
// found a packet
// done with this processing session
foundpacket = NMEA_UNKNOWN;
break;
}
}
}
if(foundpacket)
{
// check message type and process appropriately
if(!strncmp(NmeaPacket, "GPGGA", 5))
{
// process packet of this type
nmeaProcessGPGGA(NmeaPacket);
// report packet type
foundpacket = NMEA_GPGGA;
}
else if(!strncmp(NmeaPacket, "GPVTG", 5))
{
// process packet of this type
nmeaProcessGPVTG(NmeaPacket);
// report packet type
foundpacket = NMEA_GPVTG;
}
}
else if(rxBuffer->datalength >= rxBuffer->size)
{
// if we found no packet, and the buffer is full
// we're logjammed, flush entire buffer
bufferFlush(rxBuffer);
}
return foundpacket;
}
void nmeaProcessGPGGA(u08* packet)
{
u08 i;
char* endptr;
double degrees, minutesfrac;
#ifdef NMEA_DEBUG_GGA
rprintf("NMEA: ");
rprintfStr(packet);
rprintfCRLF();
#endif
// start parsing just after "GPGGA,"
i = 6;
// attempt to reject empty packets right away
if(packet[i]==',' && packet[i+1]==',')
return;
// get UTC time [hhmmss.sss]
GpsInfo.PosLLA.TimeOfFix.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: latitude
// get latitude [ddmm.mmmmm]
GpsInfo.PosLLA.lat.f = strtod(&packet[i], &endptr);
// convert to pure degrees [dd.dddd] format
minutesfrac = modf(GpsInfo.PosLLA.lat.f/100, &degrees);
GpsInfo.PosLLA.lat.f = degrees + (minutesfrac*100)/60;
// convert to radians
GpsInfo.PosLLA.lat.f *= (M_PI/180);
while(packet[i++] != ','); // next field: N/S indicator
// correct latitute for N/S
if(packet[i] == 'S') GpsInfo.PosLLA.lat.f = -GpsInfo.PosLLA.lat.f;
while(packet[i++] != ','); // next field: longitude
// get longitude [ddmm.mmmmm]
GpsInfo.PosLLA.lon.f = strtod(&packet[i], &endptr);
// convert to pure degrees [dd.dddd] format
minutesfrac = modf(GpsInfo.PosLLA.lon.f/100, &degrees);
GpsInfo.PosLLA.lon.f = degrees + (minutesfrac*100)/60;
// convert to radians
GpsInfo.PosLLA.lon.f *= (M_PI/180);
while(packet[i++] != ','); // next field: E/W indicator
// correct latitute for E/W
if(packet[i] == 'W') GpsInfo.PosLLA.lon.f = -GpsInfo.PosLLA.lon.f;
while(packet[i++] != ','); // next field: position fix status
// position fix status
// 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPS
// check for good position fix
if( (packet[i] != '0') && (packet[i] != ',') )
GpsInfo.PosLLA.updates++;
while(packet[i++] != ','); // next field: satellites used
// get number of satellites used in GPS solution
GpsInfo.numSVs = atoi(&packet[i]);
while(packet[i++] != ','); // next field: HDOP (horizontal dilution of precision)
while(packet[i++] != ','); // next field: altitude
// get altitude (in meters)
GpsInfo.PosLLA.alt.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: altitude units, always 'M'
while(packet[i++] != ','); // next field: geoid seperation
while(packet[i++] != ','); // next field: seperation units
while(packet[i++] != ','); // next field: DGPS age
while(packet[i++] != ','); // next field: DGPS station ID
while(packet[i++] != '*'); // next field: checksum
}
void nmeaProcessGPVTG(u08* packet)
{
u08 i;
char* endptr;
#ifdef NMEA_DEBUG_VTG
rprintf("NMEA: ");
rprintfStr(packet);
rprintfCRLF();
#endif
// start parsing just after "GPVTG,"
i = 6;
// attempt to reject empty packets right away
if(packet[i]==',' && packet[i+1]==',')
return;
// get course (true north ref) in degrees [ddd.dd]
GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: 'T'
while(packet[i++] != ','); // next field: course (magnetic north)
// get course (magnetic north ref) in degrees [ddd.dd]
//GpsInfo.VelHS.heading.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: 'M'
while(packet[i++] != ','); // next field: speed (knots)
// get speed in knots
//GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: 'N'
while(packet[i++] != ','); // next field: speed (km/h)
// get speed in km/h
GpsInfo.VelHS.speed.f = strtod(&packet[i], &endptr);
while(packet[i++] != ','); // next field: 'K'
while(packet[i++] != '*'); // next field: checksum
GpsInfo.VelHS.updates++;
}

View File

@ -1,53 +0,0 @@
/*! \file nmea.h \brief NMEA protocol function library. */
//*****************************************************************************
//
// File Name : 'nmea.h'
// Title : NMEA protocol function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 2002.08.27
// Revised : 2002.08.27
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef NMEA_H
#define NMEA_H
#include "global.h"
#include "buffer.h"
// constants/macros/typdefs
#define NMEA_BUFFERSIZE 80
// Message Codes
#define NMEA_NODATA 0 // No data. Packet not available, bad, or not decoded
#define NMEA_GPGGA 1 // Global Positioning System Fix Data
#define NMEA_GPVTG 2 // Course over ground and ground speed
#define NMEA_GPGLL 3 // Geographic position - latitude/longitude
#define NMEA_GPGSV 4 // GPS satellites in view
#define NMEA_GPGSA 5 // GPS DOP and active satellites
#define NMEA_GPRMC 6 // Recommended minimum specific GPS data
#define NMEA_UNKNOWN 0xFF// Packet received but not known
// Debugging
//#define NMEA_DEBUG_PKT ///< define to enable debug of all NMEA messages
//#define NMEA_DEBUG_GGA ///< define to enable debug of GGA messages
//#define NMEA_DEBUG_VTG ///< define to enable debug of VTG messages
// functions
void nmeaInit(void);
u08* nmeaGetPacketBuffer(void);
u08 nmeaProcess(cBuffer* rxBuffer);
void nmeaProcessGPGGA(u08* packet);
void nmeaProcessGPVTG(u08* packet);
#endif

View File

@ -1,98 +0,0 @@
/*! \file port128.h \brief Additional include for Mega128 to define individual port pins. */
//*****************************************************************************
//
// File Name : 'port128.h'
// Title : Additional include for Mega128 to define individual port pins
// Author : Pascal Stang
// Created : 11/18/2002
// Revised : 11/18/2002
// Version : 1.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This include file contains additional port and pin defines
// to help make code transparently compatible with the mega128. As in
// the other AVR processors, using defines like PD2 to denote PORTD, pin2
// is not absolutely necessary but enhances readability. The mega128 io.h
// no longer defines individual pins of ports (like PD2 or PA5, for
// example). Instead, port pins are defines universally for all ports as
// PORT0 through PORT7. However, this renaming causes a code-portability
// issue from non-mega128 AVRs to the mega128. Including this file will
// replace the missing defines.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef PORT128_H
#define PORT128_H
// Mega128 individual port defines
// (using these is technically unnecessary but improves code compatibility to
// the mega128 from other AVR processors where these values were still defined
// in the io.h for that processor)
// PORTA
#define PA0 PORT0
#define PA1 PORT1
#define PA2 PORT2
#define PA3 PORT3
#define PA4 PORT4
#define PA5 PORT5
#define PA6 PORT6
#define PA7 PORT7
// PORTB
#define PB0 PORT0
#define PB1 PORT1
#define PB2 PORT2
#define PB3 PORT3
#define PB4 PORT4
#define PB5 PORT5
#define PB6 PORT6
#define PB7 PORT7
// PORTC
#define PC0 PORT0
#define PC1 PORT1
#define PC2 PORT2
#define PC3 PORT3
#define PC4 PORT4
#define PC5 PORT5
#define PC6 PORT6
#define PC7 PORT7
// PORTD
#define PD0 PORT0
#define PD1 PORT1
#define PD2 PORT2
#define PD3 PORT3
#define PD4 PORT4
#define PD5 PORT5
#define PD6 PORT6
#define PD7 PORT7
// PORTE
#define PE0 PORT0
#define PE1 PORT1
#define PE2 PORT2
#define PE3 PORT3
#define PE4 PORT4
#define PE5 PORT5
#define PE6 PORT6
#define PE7 PORT7
// PORTF
#define PF0 PORT0
#define PF1 PORT1
#define PF2 PORT2
#define PF3 PORT3
#define PF4 PORT4
#define PF5 PORT5
#define PF6 PORT6
#define PF7 PORT7
// PORTG
#define PG0 PORT0
#define PG1 PORT1
#define PG2 PORT2
#define PG3 PORT3
#define PG4 PORT4
#define PG5 PORT5
#endif

View File

@ -1,286 +0,0 @@
/*! \file pulse.c \brief Pulse/frequency generation function library. */
//*****************************************************************************
//
// File Name : 'pulse.c'
// Title : Pulse/frequency generation function library
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 2002-08-19
// Revised : 2003-05-29
// Version : 0.7
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#endif
#include "global.h"
#include "timer.h"
#include "pulse.h"
// Global variables
// pulse generation registers
volatile static unsigned char PulseT1AMode;
volatile static unsigned short PulseT1ACount;
volatile static unsigned short PulseT1APeriodTics;
volatile static unsigned char PulseT1BMode;
volatile static unsigned short PulseT1BCount;
volatile static unsigned short PulseT1BPeriodTics;
// pulse mode bit definitions
// PULSE_MODE_COUNTED
// if true, the requested number of pulses are output, then output is turned off
// if false, pulses are output continuously
#define PULSE_MODE_CONTINUOUS 0x00
#define PULSE_MODE_COUNTED 0x01
// functions
void pulseInit(void)
{
// initialize timer1 for pulse operation
pulseT1Init();
}
void pulseT1Init(void)
{
// try to make sure that timer1 is in "normal" mode
// most importantly, turn off PWM mode
timer1PWMOff();
// set some reasonable initial values
// in case the user forgets to
PulseT1AMode = 0;
PulseT1BMode = 0;
PulseT1ACount = 0;
PulseT1BCount = 0;
PulseT1APeriodTics = 0x8000;
PulseT1BPeriodTics = 0x8000;
// attach the pulse service routines to
// the timer 1 output compare A and B interrupts
timerAttach(TIMER1OUTCOMPAREA_INT,pulseT1AService);
timerAttach(TIMER1OUTCOMPAREB_INT,pulseT1BService);
}
void pulseT1Off(void)
{
// turns pulse outputs off immediately
// set pulse counters to zero (finished)
PulseT1ACount = 0;
PulseT1BCount = 0;
// disconnect OutputCompare action from OC1A pin
cbi(TCCR1A,COM1A1);
cbi(TCCR1A,COM1A0);
// disconnect OutputCompare action from OC1B pin
cbi(TCCR1A,COM1B1);
cbi(TCCR1A,COM1B0);
// detach the pulse service routines
timerDetach(TIMER1OUTCOMPAREA_INT);
timerDetach(TIMER1OUTCOMPAREB_INT);
}
void pulseT1ASetFreq(u16 freqHz)
{
// set the frequency of the pulse output
// we need to find the requested period/2 (in timer tics)
// from the frequency (in hertz)
// calculate how many tics in period/2
// this is the (timer tic rate)/(2*requested freq)
PulseT1APeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz));
}
void pulseT1BSetFreq(u16 freqHz)
{
// set the frequency of the pulse output
// we need to find the requested period/2 (in timer tics)
// from the frequency (in hertz)
// calculate how many tics in period/2
// this is the (timer tic rate)/(2*requested freq)
PulseT1BPeriodTics = ((u32)F_CPU/((u32)timer1GetPrescaler()*2*freqHz));
}
void pulseT1ARun(u16 nPulses)
{
// set the number of pulses we want and the mode
if(nPulses)
{
// if the nPulses is non-zero, use "counted" mode
PulseT1AMode |= PULSE_MODE_COUNTED;
PulseT1ACount = nPulses<<1;
}
else
{
// if nPulses is zero, run forever
PulseT1AMode &= ~PULSE_MODE_COUNTED;
PulseT1ACount = 1<<1;
}
// set OutputCompare action to toggle OC1A pin
cbi(TCCR1A,COM1A1);
sbi(TCCR1A,COM1A0);
// now the "enabling" stuff
// set the output compare one pulse cycle ahead of current timer position
// to make sure we don't have to wait until the timer overflows and comes
// back to the current value
// set future output compare time to TCNT1 + PulseT1APeriodTics
//outw(OCR1A, inw(TCNT1) + PulseT1APeriodTics);
OCR1A += PulseT1APeriodTics;
// enable OutputCompare interrupt
sbi(TIMSK, OCIE1A);
}
void pulseT1BRun(u16 nPulses)
{
// set the number of pulses we want and the mode
if(nPulses)
{
// if the nPulses is non-zero, use "counted" mode
PulseT1BMode |= PULSE_MODE_COUNTED;
PulseT1BCount = nPulses<<1;
}
else
{
// if nPulses is zero, run forever
PulseT1BMode &= ~PULSE_MODE_COUNTED;
PulseT1BCount = 1<<1;
}
// set OutputCompare action to toggle OC1B pin
// (note: with all the A's and B's flying around, TCCR1A is not a bug)
cbi(TCCR1A,COM1B1);
sbi(TCCR1A,COM1B0);
// now the "enabling" stuff
// set the output compare one pulse cycle ahead of current timer position
// to make sure we don't have to wait until the timer overflows and comes
// back to the current value
// set future output compare time to TCNT1 + PulseT1APeriodTics
//outw(OCR1B, inw(TCNT1) + PulseT1BPeriodTics);
OCR1B += PulseT1BPeriodTics;
// enable OutputCompare interrupt
sbi(TIMSK, OCIE1B);
}
void pulseT1AStop(void)
{
// stop output regardless of remaining pulses or mode
// go to "counted" mode
PulseT1AMode |= PULSE_MODE_COUNTED;
// set pulses to zero
PulseT1ACount = 0;
}
void pulseT1BStop(void)
{
// stop output regardless of remaining pulses or mode
// go to "counted" mode
PulseT1BMode |= PULSE_MODE_COUNTED;
// set pulses to zero
PulseT1BCount = 0;
}
u16 pulseT1ARemaining(void)
{
// return the number of pulses remaining for channel A
// add 1 to make sure we round up, >>1 equivalent to /2
return (PulseT1ACount+1)>>1;
}
u16 pulseT1BRemaining(void)
{
// return the number of pulses remaining for channel A
// add 1 to make sure we round up, >>1 equivalent to /2
return (PulseT1BCount+1)>>1;
}
void pulseT1AService(void)
{
// check if TimerPulseACount is non-zero
// (i.e. pulses are still requested)
if(PulseT1ACount)
{
//u16 OCValue;
// read in current value of output compare register OCR1A
//OCValue = inp(OCR1AL); // read low byte of OCR1A
//OCValue += inp(OCR1AH)<<8; // read high byte of OCR1A
// increment OCR1A value by PulseT1APeriodTics
//OCValue += PulseT1APeriodTics;
// set future output compare time to this new value
//outp((OCValue>>8), OCR1AH); // write high byte
//outp((OCValue & 0x00FF),OCR1AL); // write low byte
// the following line should be identical in operation
// to the lines above, but for the moment, I'm not convinced
// this method is bug-free. At least it's simpler!
//outw(OCR1A, inw(OCR1A) + PulseT1APeriodTics);
// change again
OCR1A += PulseT1APeriodTics;
// decrement the number of pulses executed
if(PulseT1AMode & PULSE_MODE_COUNTED)
PulseT1ACount--;
}
else
{
// pulse count has reached zero
// disable the output compare's action on OC1A pin
cbi(TCCR1A,COM1A1);
cbi(TCCR1A,COM1A0);
// and disable the output compare's interrupt to stop pulsing
cbi(TIMSK, OCIE1A);
}
}
void pulseT1BService(void)
{
// check if TimerPulseACount is non-zero
// (i.e. pulses are still requested)
if(PulseT1BCount)
{
//u16 OCValue;
// read in current value of output compare register OCR1B
//OCValue = inp(OCR1BL); // read low byte of OCR1B
//OCValue += inp(OCR1BH)<<8; // read high byte of OCR1B
// increment OCR1B value by PulseT1BPeriodTics
//OCValue += PulseT1BPeriodTics;
// set future output compare time to this new value
//outp((OCValue>>8), OCR1BH); // write high byte
//outp((OCValue & 0x00FF),OCR1BL); // write low byte
// the following line should be identical in operation
// to the lines above, but for the moment, I'm not convinced
// this method is bug-free. At least it's simpler!
//outw(OCR1B, inw(OCR1B) + PulseT1BPeriodTics);
// change again
OCR1B += PulseT1BPeriodTics;
// decrement the number of pulses executed
if(PulseT1BMode & PULSE_MODE_COUNTED)
PulseT1BCount--;
}
else
{
// pulse count has reached zero
// disable the output compare's action on OC1B pin
cbi(TCCR1A,COM1B1);
cbi(TCCR1A,COM1B0);
// and disable the output compare's interrupt to stop pulsing
cbi(TIMSK, OCIE1B);
}
}

View File

@ -1,98 +0,0 @@
/*! \file pulse.h \brief Pulse/frequency generation function library. */
//*****************************************************************************
//
// File Name : 'pulse.h'
// Title : Pulse/frequency generation function library
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 2002-08-19
// Revised : 2003-05-29
// Version : 0.7
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// Description : This library is designed to facilitate the output of square
// wave pulses at a frequency determined by the user. The library uses
// the AVR processor built-in timers and the output is on the timer Output
// Compare (OC) pins.
//
// The allowable range of frequencies which can be generated is governed
// by the tic rate of the timer (therefore the CPU clock rate and the
// timer prescaler), and the computing speed of the processor itself. See
// the SetFreq commands for more details.
//
// NOTE: in order for the pulse library to work, pulseInit() will attach
// the pulse service routines to the timer interrupts using the
// timerAttach function. You must not detach the service routines during
// pulse library operation.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef PULSE_H
#define PULSE_H
#include "global.h"
// constants/macros/typdefs
// functions
// Master Pulse Commands
// pulseInit()
// Initializes the pulse system/library.
void pulseInit(void);
// Pulse commands for timer1
// pulseT1Init()
// configures the timer1 hardware to produce pulses on pins OC1A and OC1B.
// A "pulse" is considered to be one high and low period of a square wave.
void pulseT1Init(void);
// pulseT1Off()
// Turns pulse output off immediately (cancels running pulse operations).
// Unconfigures hardware and interrupts.
void pulseT1Off(void);
// pulseT1ASetFreq() and pulseT1BSetFreq()
// sets the frequency in hertz for each channel of square-wave pulse output
// Note1: the freqency <freqHz> must always be greater than zero
// Note2: both channels share the same frequency range which is governed
// by the timer1 prescaler setting. A prescaler setting of DIV/8 allows
// frequencies of a few hertz through a few kilohertz.
//
// Lower frequency bound = overflow rate of timer1 at current prescaling
// Upper frequency bound = the tics rate of timer1 at current prescaling,
// or approx. the (clock rate of the processor)/50,
// whichever is smaller
void pulseT1ASetFreq(u16 freqHz);
void pulseT1BSetFreq(u16 freqHz);
// pulseT1ARun() and pulseT1BRun();
// Sets the number of square-wave pulses to be output on the given channel.
// For continuous (unlimited) pulse output, use nPulses = 0. Pulses begin
// coming out immediately.
// Note: <nPulses> must be between 0 and 32767
void pulseT1ARun(u16 nPulses);
void pulseT1BRun(u16 nPulses);
// pulseT1AStop() and pulseT1BStop();
// Stop pulse output at the next cycle (regardless of the number of
// remaining pulses).
void pulseT1AStop(void);
void pulseT1BStop(void);
// pulseT1ARemaining() and pulseT1BRemaining()
// Returns the number of pulses remaining to be output for each channel.
// This function is useful for figuring out if the pulses are done.
u16 pulseT1ARemaining(void);
u16 pulseT1BRemaining(void);
// pulseT1AService() and pulseT1BService()
// Interrupt service routines for pulse output (do not call these functions directly)
void pulseT1AService(void);
void pulseT1BService(void);
#endif

View File

@ -1,153 +0,0 @@
/*! \file pwmsw.c \brief Software interrupt-driven multi-output PWM function library. */
//*****************************************************************************
//
// File Name : 'pwmsw.c'
// Title : Software interrupt-driven multi-output PWM function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 7/20/2002
// Revised : 7/31/2002
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// WARNING: this PWM library does not work perfectly. It has known and
// understood problems when two or more PWM outputs are set to nearly the
// same duty cycle. IT MAY NOT BE WORTH USING! YOU HAVE BEEN WARNED!
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef WIN32
#include <avr/io.h>
#endif
#include "global.h"
#include "pwmsw.h"
// Program ROM constants
// Global variables
// PWM channel registers
u16 PosTics;
u16 PeriodTics;
u08 Channel;
SwPwmChannelType SwPwmChannels[SWPWM_NUM_CHANNELS];
// functions
// initializes software PWM system
void pwmswInit(u16 periodTics)
{
u08 index;
// attach the software PWM service routine to timer1 output compare A
timerAttach(TIMER1OUTCOMPAREA_INT, pwmswService);
// set PeriodTics
PeriodTics = periodTics;
// set PosTics
PosTics = 0;
// clear channels
for(index=0; index<SWPWM_NUM_CHANNELS; index++)
{
SwPwmChannels[index].duty = 0;
SwPwmChannels[index].setduty = 0;
}
// set initial interrupt time
u16 OCValue;
// read in current value of output compare register OCR1A
OCValue = inb(OCR1AL); // read low byte of OCR1A
OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A
// increment OCR1A value by nextTics
OCValue += PeriodTics;
// set future output compare time to this new value
outb(OCR1AH, (OCValue>>8)); // write high byte
outb(OCR1AL, (OCValue & 0x00FF)); // write low byte
// enable the timer1 output compare A interrupt
sbi(TIMSK, OCIE1A);
}
// turns off software PWM system
void pwmswOff(void)
{
// disable the timer1 output compare A interrupt
cbi(TIMSK, OCIE1A);
// detach the service routine
timerDetach(TIMER1OUTCOMPAREA_INT);
}
// set duty on channel
void pwmswPWMSet(u08 channel, u16 duty)
{
// compare with max value of PeriodTics
duty = MIN(duty, PeriodTics);
SwPwmChannels[channel].setduty = duty;
}
void pwmswService(void)
{
u16 nextTics=PeriodTics;
u08 index;
// check for beginning of period
if(PosTics == 0)
{
// examine all channels
for(index=0; index<SWPWM_NUM_CHANNELS; index++)
{
// transfer set-duty to active-duty
SwPwmChannels[index].duty = SwPwmChannels[index].setduty;
// find next channel event to schedule
// if no channel has a duty setting greater than 0 (PosTics);
// nextTics will remain at PeriodTics for the next cycle
if(SwPwmChannels[index].duty)
{
nextTics = MIN(nextTics, SwPwmChannels[index].duty);
// set all non-zero channels to on
outb(SWPWMPORT, inb(SWPWMPORT) | (1<<index));
}
}
}
else
{
// examine all channels
for(index=0; index<SWPWM_NUM_CHANNELS; index++)
{
// check if we have a duty cycle match
if(PosTics == SwPwmChannels[index].duty)
{
// clear output channel
outb(SWPWMPORT, inb(SWPWMPORT) & ~(1<<index));
}
// find next channel event to schedule
// if no channel has a duty setting greater than PosTics;
// nextTics will remain at PeriodTics and is handled below
if(SwPwmChannels[index].duty > PosTics)
nextTics = MIN(nextTics, SwPwmChannels[index].duty-PosTics);
}
if(nextTics == PeriodTics)
{
// no more channels to schedule
// schedule next cycle
nextTics = PeriodTics - PosTics;
}
}
// schedule next interrupt
u16 OCValue;
// read in current value of output compare register OCR1A
OCValue = inb(OCR1AL); // read low byte of OCR1A
OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A
// increment OCR1A value by nextTics
OCValue += nextTics;
// OCR1A+=nextTics;
// set future output compare time to this new value
outb(OCR1AH, (OCValue>>8)); // write high byte
outb(OCR1AL, (OCValue & 0x00FF)); // write low byte
// set our new tic position
PosTics += nextTics;
if(PosTics >= PeriodTics) PosTics -= PeriodTics;
}

View File

@ -1,57 +0,0 @@
/*! \file pwmsw.h \brief Software interrupt-driven multi-output PWM function library. */
//*****************************************************************************
//
// File Name : 'pwmsw.h'
// Title : Software interrupt-driven multi-output PWM function library
// Author : Pascal Stang - Copyright (C) 2002
// Created : 7/20/2002
// Revised : 7/31/2002
// Version : 0.1
// Target MCU : Atmel AVR Series
// Editor Tabs : 4
//
// WARNING: this PWM library does not work perfectly. It has known and
// understood problems when two or more PWM outputs are set to nearly the
// same duty cycle. IT MAY NOT BE WORTH USING! YOU HAVE BEEN WARNED!
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef PWMSW_H
#define PWMSW_H
#include "global.h"
#include "timer.h"
// constants/macros/typdefs
typedef struct struct_SwPwmChannel
{
u08 port; ///< channel's hardware I/O port
u08 pin; ///< channel's hardware I/O pin
u16 duty; ///< active PWM duty setting
u16 setduty; ///< requested PWM duty setting
} SwPwmChannelType;
// number of PWM channels
#define SWPWM_NUM_CHANNELS 3
// define port
#define SWPWMPORT PORTB
#define SWPWMDDR DDRB
// functions
//! initializes software PWM system
void pwmswInit(u16 periodTics);
//! turns off software PWM system
void pwmswOff(void);
//! set duty on channel
void pwmswPWMSet(u08 channel, u16 duty);
//! software PWM interrupt service routine
void pwmswService(void);
#endif

View File

@ -1,340 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Procyon AVRlib Release Notes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<!--#config timefmt="%a %b %d, %Y" -->
<h1 align="center">Procyon AVRlib Release Notes</h1>
<center>Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
<hr>
<p><strong>3/12/2005</strong>
<ul>
<li>Fixed AVRlib to comply to new WinAVR package (avr-libc has dropped several
methods that were depricated causing the old AVRlib to fail to compile). Sorry
about the delay. Please note that I've changed small parts of dozens of files.
I may have introduced bugs that I haven't yet detected. Your feedback welcome.</li>
</ul>
<p><strong>1/30/2005</strong>
<ul>
<li>Added new <strong>lis3l02</strong> accelerometer library. This ST accelerometer
incorporates a 3-axis sensor and A/D converter in one 28-pin SOIC package
with I2C and SPI bus. Unfortunately, the production future of the digital
version of this accelerometer is unknown.</li>
<li>Added new <strong>extint</strong> external interrupt library. The library
is not complete, but does work nicely for some processors. It is primarily
designed to do two things:
<ul>
<li>abstract AVR external interrupts so that programs which use them can
more easily cross-compile between different processors</li>
<li>allow novice (and even advanced) users to be able to use external interrupts
without looking up a bunch of register and bit defines in the datasheets.</li>
</ul>
</li>
<li>Revised GPS library to standardize on units used for latitude/longitude
angles</li>
<li>Improved NMEA library. Packet processing function now returns type of packet
decoded. Packet parsers reject valid but empty packets.</li>
<li>MMC library has proper #defines to turn on/off debugging statements</li>
<li>uartsw and uartsw2 libraries now support optional inversion of serial signal
via #define in conf file</li>
</ul>
<p><strong></strong><strong>10/15/2004</strong>
<ul>
<li>Added new spieeprom library. Not quite sure if it works properly.</li>
</ul>
<p><strong></strong><strong>9/25/2004</strong>
<ul>
<li>Added a simple MultiMedia Card / SecureDigital Card interface library. The
library allows you to read and write sector-sized (512 byte) data chunks.
Please see mmc.h for information about how to connect the card to the microcontroller.</li>
<li>Added uartGetByte() functions to uart.c and uart2.c. These functions emulate
the typical getchar() function and return a received character if available,
otherwise -1.</li>
<li>Fixed bug causing incorrect I2C bus speed.</li>
</ul>
<p><strong>6/25/2004</strong>
<ul>
<li>Changed encoder library to new read-in scheme which is more technically
correct and resistant to error. New scheme counts both rising and falling
edges of PHASEA, so be prepared for twice the precision (you'll get double
the usual number of counts per revolution).</li>
<li>Added timer functions to exploit arbitrary frequency/precision PWM in new
AVR processors</li>
<li>Fixed timerPause() precision management bug in Timer/Timer128 libraries.<br>
TimerPause function should now work correctly for longer delays</li>
<li>Added timerXGetPrescaler() functions to timer libraries to avoid code maintenance
issues and to reduce overall code size</li>
<li>Fixed bug in Pulse library that cause wildly incorrect frequencies to be
produced</li>
</ul>
<p><strong>5/04/2004</strong>
<ul>
<li>Added MegaIO directory with simple routines for accessing the MegaIO peripheral
expander. MegaIO allows you to use a slave AVR processor as a peripheral expander
and control it easily from a master AVR processor over the I2C bus. This gives
your master processor easy access to: an extra buffered UART, extra PWM outputs,
extra A/D inputs, extra I/O lines, extra RAM, and more.</li>
</ul>
<p><strong>2/27/2004</strong>
<ul>
<li>Improved original Software UART library (uartsw: uses Timer1 OC1A OC1B and
IC1)</li>
<li>Added new Software UART library (uartsw2: uses Timer0 and Timer2 and INT2)</li>
<li>Fixed small but catastrophic bug in the Software Memory Bus (sramsw)</li>
<li>Fixed small but catastrophic bug in the Timer library when using Timer 0
Output Compare</li>
<li>Fixed Timer128 library bug when using Timer 3 Output Compare B</li>
<li>Added support for ICR top-count PWM when supported by processor</li>
<li><strong>Thanks to all the users who have offered bugfixes and feedback!</strong></li>
</ul>
<p><strong>2/22/2004</strong>
<ul>
<li>Added ADS7828 I2C A/D Converter Library + example code</li>
<li>Added DS1631 I2C Temperature Sensor Library + example code</li>
<li>Timer/Timer128 Library</li>
<ol>
<li>For processor that support it, timerPause() will sleep the processor during the delay time,
thereby reducing power consumption. All interrupts are still active so hopefully this shouldn't
break anybody's code.</li>
<li>The timer library will now compile properly for the processors with only timers 0,1
(by excluding timer2 functions automatically)</li>
<li>Bugfix on Timer3 initialization</li>
<li>A big thanks to those that wrote in to report bugs or offer suggestions for improvement!</li>
</ol>
<li>Servo Library: optimized slightly</li>
<li>UART/UART2 Library: Improved compile compatibility across more AVR processors</li>
</ul>
<p><strong>9/15/2003</strong>
<ul>
<li>I2C Library
<ol>
<li>A few bugfixes here. i2cMasterSend and i2cMasterReceive finally return
error values if the target device is not present. This is especially important
in the case of receive because that would otherwise hang. Some debugging
has been added to the I2C interrupt state machine. Debugging can be turned
on via #define but needs to be customized based on the processor in use.</li>
</ol>
</ul>
<p><strong>7/23/2003</strong>
<ul>
<li>Cmdline Library (<strong>NEW</strong>)
<ol>
<li>This library is a complete fairly-easy-to-use command line interface
complete with advanced line editing and history buffer. You add the commands
and the functions to run for those commands. The arguments passed to your
commands are available as strings or interpreted as decimal or hex integers.</li>
</ol>
<li>Uart/Uart2 Library
<ol>
<li>Added a new method uartAddToTxBuffer() which adds one character at a
time to the uart transmit buffer. The function can be used the the same
way as uartSendByte, but writes only to the buffer. This is helpful for
printf-ing inside interrupts or time-critical sections.</li>
</ol>
<li>i2ceeprom function library
<ol>
<li>Fixed a compile bug that escaped last time.</li>
<li>Bugfix: there was an endian-ness discrepancy between the read and write
byte routines for the eeprom. Problem has been fixed thanks to feedback
from users.</li>
</ol>
</ul>
<p><strong>7/12/2003</strong>
<ul>
<li>General Note
<ol>
<li>CAUTION: The makefile and build process for AVRlib has changed to make
installation and management simpler. You will need to define an AVRLIB
environment variable to point to the location where you keep AVRlib. See
the revised installation guide for more details.</li>
<li>I made a lot of small fixes to various libraries without properly recording
the changes. Sorry.</li>
</ol>
<li>STX/ETX function library
<ol>
<li>The receiving packet engine has been revised for the stx/etx protocol.
It's somewhat less stupidly coded now and should perform better. Fixed
a bug that made servicing an empty receive buffer excessively long.</li>
</ol>
<li>Timer/Timer128 function library
<ol>
<li>Since the creation of the timer library, the timerPause function had
a bug/deficiency which caused it to be either slightly or grossly off
in timing depending on the delay requested and the current prescaler setting.
This bug is now fixed at the expense of a little extra code and timing
performance should be considerably more accurate.</li>
</ol>
</ul>
<p><strong>6/06/2003</strong>
<ul>
<li>General Note
<ol>
<li>I've recently seen the need for more project-dependent configurable
settings in the core AVRlib libraries (uart, timer, rprintf). Rather than
creating a smorgasboard of new &quot;conf&quot; files to handle the settings,
I've decided to handle most things via #ifdefs and user-optional #defines.
My feeling is that for core libraries, it nice to not have to lug around
&quot;conf&quot; files all the time. We'll see how it goes...</li>
</ol>
<li>UART and UART2 function libraries
<ol>
<li>You can now override the default UART receive handling (placing of the
data into the receive buffer), by using the uartSetRxHandler() function
and providing your own function.</li>
<li>You can now adjust the default size of the UART Rx/Tx buffers by #defining
the size before including uart.h. I recommend placing such #defines in
your global.h.</li>
</ol>
<li>UARTSW function library
<ol>
<li>Out of personal need, I have finally gotten the software-driven UART
code working. Please consider this an alpha release. It works well, but
the library is still in flux.</li>
</ol>
<li>A2D function library
<ol>
<li>Efforts are being made to make the A2D functions compatible (compile
transparently) over a greater range of AVR processors including the new
Mega8,16,32,64. Please be patient if proper support for your processor
is temporarily broken.</li>
</ol>
<li>Timer/Timer128 function library
<ol>
<li>#defines have been added to specify the timer prescaler rates on RealTimeClock-equipped
timer. You may have noticed that the RTC-equipped timer always has a different
prescaler selection range than the other timers. You must use the new
TIMERRTC_CLK_DIV defines instead of the TIMER_CLK_DIV defines on these
timers, otherwise you will get wrong results. </li>
<li>You can now change the default interrupt handler type (INTERRUPT vs.
SIGNAL) used for the timers by #defining it before including timer.h.
I recommend placing such #defines in your global.h.</li>
</ol>
</ul>
<p><strong>5/29/2003</strong>
<ul>
<li>Pulse function library
<ol>
<li>There are two new functions PulseT1AStop() and PulseT1BStop(), that
allow the stopping of pulse output regardless of the previously programmed
number of pulses to be output. The new stop commands are crucial when
using the continuous pulse output mode.</li>
</ol>
</ul>
<p><strong>5/1/2003</strong>
<ul>
<li>KS0108 Graphic LCD driver library
<ol>
<li>Made some improvements to the code structure and #define names, eliminates
some unnecessary lines.</li>
<li>Implemented <font color="#FF0000">untested</font> support for up to
4 controller chips (240x64 pixel display).</li>
</ol>
<li>rprintf library
<ol>
<li>Thanks to some feedback, and some testing, I recently realized I had
doubled the compiled size of the printf library when I added a floating-point
print function a several months ago.</li>
<li>The floating-point print can now be enabled or disabled in the rprintfconf.h
file. (it is disabled by default)</li>
</ol>
</li>
</ul>
<p><strong>4/30/2003</strong>
<ul>
<li>Uart function library
<ol>
<li>Like the timer library, you can now universally switch from SIGNAL-type
interrupt handlers to INTERRUPT-type handlers by changing a #define in
uart.h or uart2.h. Note, for the time being, I'm avoiding creating a &quot;conf&quot;
file for the uart libraries because of their widespread use. Don't want
to confuse users any mor than I have to.</li>
</ol>
<li>Pulse function library </li>
<ol>
<li>Fixed a major bug which caused some pulse output requests to idle until
the timer overflowed</li>
</ol>
<li>ATA/IDE interface driver</li>
<ol>
<li>Brought this code out of basic disrepair and into service again - effort
will continue as time permits</li>
</ol>
<li>FAT filesystem driver
<ol>
<li>Brought this code out of basic disrepair and into service again - effort
will continue as time permits</li>
<li>Will attempt to improve the overall interface for FAT as well as begin
to support file writing</li>
</ol>
</li>
</ul>
<p><strong>3/13/2003</strong>
<ul>
<li>New &quot;debug&quot; function library
<ol>
<li>Added a new library for general functions useful when debugging. Currently
the only available function is for nicely formatted hex/ascii table dumps
(useful when inspecting memory or buffers).</li>
</ol>
</li>
</ul>
<p><strong>3/2/2003</strong>
<ul>
<li>I2C Library
<ol>
<li>Continued updating of I2C library - NOTE: some old functions have changed
names slightly to clarify their purpose and relationship to new functions.</li>
<li>Added two function pointers designed to be set by the user to handle
incoming Slave Receive and Slave Transmit operations.</li>
<li>Added i2cMasterTransfer function which does the common write-then-read
operation with repeated start in between so control of the bus is not
lost. This kind of access is common when accessing memories or register
based devices where the address must be written before reading back a
value. </li>
<li>NOTE: Structure of the library continues to change but has solidified
substantially.</li>
</ol>
</li>
</ul>
</p>
<p><strong>2/24/2003</strong>
<ul>
<li>Encoder Library
<ol>
<li>Improved interrupt flexibility and processor compatibility for this library</li>
<li>Unfortunately, the complexity comes at the cost of a somewhat more complicated
encoderconf.h which the user must edit to suit their specific needs on a per-project basis.</li>
</ol>
</li>
<li>I2C Library
<ol>
<li>Second major revision of I2C library in an attempt to make it general enough to use for
any common I2C operations.</li>
<li>Changes include the "functionalizing" of basic low-level I2C operations
such as generate start,stop, and send address/data.</li>
<li>NOTE: Structure of the library has changed somewhat and will likely continue to be refined.</li>
</ol>
</li>
<li>Timer128 Library
<ol>
<li>Added missing PWM on and off functions in Timer128 library</li>
</ol>
</li>
</ul>
</p>
<p><strong>2/24/2003</strong>
<ul>
<li>Release Notes Started</li>
</ul>
</p>
<hr>
<center>Written by Pascal Stang | Updated:
<!--#echo var="LAST_MODIFIED" -->
</center>
</body>
</html>

View File

@ -1,773 +0,0 @@
/*! \file rprintf.c \brief printf routine and associated routines. */
//*****************************************************************************
//
// File Name : 'rprintf.c'
// Title : printf routine and associated routines
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 2000.12.26
// Revised : 2003.5.1
// Version : 1.0
// Target MCU : Atmel AVR series and other targets
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/pgmspace.h>
//#include <string-avr.h>
//#include <stdlib.h>
#include <stdarg.h>
#include "global.h"
#include "rprintf.h"
#ifndef TRUE
#define TRUE -1
#define FALSE 0
#endif
#define INF 32766 // maximum field size to print
#define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr))
#ifdef RPRINTF_COMPLEX
static unsigned char buf[128];
#endif
// use this to store hex conversion in RAM
//static char HexChars[] = "0123456789ABCDEF";
// use this to store hex conversion in program memory
//static prog_char HexChars[] = "0123456789ABCDEF";
static char __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF";
// function pointer to single character output routine
static void (*rputchar)(unsigned char c);
// *** rprintf initialization ***
// you must call this function once and supply the character output
// routine before using other functions in this library
void rprintfInit(void (*putchar_func)(unsigned char c))
{
rputchar = putchar_func;
}
// *** rprintfChar ***
// send a character/byte to the current output device
inline void rprintfChar(unsigned char c)
{
// send character
rputchar(c);
}
// *** rprintfStr ***
// prints a null-terminated string stored in RAM
void rprintfStr(char str[])
{
// send a string stored in RAM
// check to make sure we have a good pointer
if (!str) return;
// print the string until a null-terminator
while (*str)
rprintfChar(*str++);
}
// *** rprintfStrLen ***
// prints a section of a string stored in RAM
// begins printing at position indicated by <start>
// prints number of characters indicated by <len>
void rprintfStrLen(char str[], unsigned int start, unsigned int len)
{
register int i=0;
// check to make sure we have a good pointer
if (!str) return;
// spin through characters up to requested start
// keep going as long as there's no null
while((i++<start) && (*str++));
// for(i=0; i<start; i++)
// {
// // keep steping through string as long as there's no null
// if(*str) str++;
// }
// then print exactly len characters
for(i=0; i<len; i++)
{
// print data out of the string as long as we haven't reached a null yet
// at the null, start printing spaces
if(*str)
rprintfChar(*str++);
else
rprintfChar(' ');
}
}
// *** rprintfProgStr ***
// prints a null-terminated string stored in program ROM
void rprintfProgStr(const prog_char str[])
{
// print a string stored in program memory
register char c;
// check to make sure we have a good pointer
if (!str) return;
// print the string until the null-terminator
while((c = pgm_read_byte(str++)))
rprintfChar(c);
}
// *** rprintfCRLF ***
// prints carriage return and line feed
void rprintfCRLF(void)
{
// print CR/LF
rprintfChar('\r');
rprintfChar('\n');
}
// *** rprintfu04 ***
// prints an unsigned 4-bit number in hex (1 digit)
void rprintfu04(unsigned char data)
{
// print 4-bit hex value
// char Character = data&0x0f;
// if (Character>9)
// Character+='A'-10;
// else
// Character+='0';
rprintfChar(pgm_read_byte( HexChars+(data&0x0f) ));
}
// *** rprintfu08 ***
// prints an unsigned 8-bit number in hex (2 digits)
void rprintfu08(unsigned char data)
{
// print 8-bit hex value
rprintfu04(data>>4);
rprintfu04(data);
}
// *** rprintfu16 ***
// prints an unsigned 16-bit number in hex (4 digits)
void rprintfu16(unsigned short data)
{
// print 16-bit hex value
rprintfu08(data>>8);
rprintfu08(data);
}
// *** rprintfu32 ***
// prints an unsigned 32-bit number in hex (8 digits)
void rprintfu32(unsigned long data)
{
// print 32-bit hex value
rprintfu16(data>>16);
rprintfu16(data);
}
// *** rprintfNum ***
// special printf for numbers only
// see formatting information below
// Print the number "n" in the given "base"
// using exactly "numDigits"
// print +/- if signed flag "isSigned" is TRUE
// use the character specified in "padchar" to pad extra characters
//
// Examples:
// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234"
// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234"
// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5"
void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n)
{
// define a global HexChars or use line below
//static char HexChars[16] = "0123456789ABCDEF";
char *p, buf[32];
unsigned long x;
unsigned char count;
// prepare negative number
if( isSigned && (n < 0) )
{
x = -n;
}
else
{
x = n;
}
// setup little string buffer
count = (numDigits-1)-(isSigned?1:0);
p = buf + sizeof (buf);
*--p = '\0';
// force calculation of first digit
// (to prevent zero from not printing at all!!!)
*--p = pgm_read_byte(HexChars + (x%base)); x /= base;
// calculate remaining digits
while(count--)
{
if(x != 0)
{
// calculate next digit
*--p = pgm_read_byte(HexChars + (x%base)); x /= base;
}
else
{
// no more digits left, pad out to desired length
*--p = padchar;
}
}
// apply signed notation if requested
if( isSigned )
{
if(n < 0)
{
*--p = '-';
}
else if(n > 0)
{
*--p = '+';
}
else
{
*--p = ' ';
}
}
// print the string right-justified
count = numDigits;
while(count--)
{
rprintfChar(*p++);
}
}
#ifdef RPRINTF_FLOAT
// *** rprintfFloat ***
// floating-point print
void rprintfFloat(char numDigits, double x)
{
unsigned char firstplace = FALSE;
unsigned char negative;
unsigned char i, digit;
double place = 1.0;
// save sign
negative = (x<0);
// convert to absolute value
x = (x>0)?(x):(-x);
// find starting digit place
for(i=0; i<15; i++)
{
if((x/place) < 10.0)
break;
else
place *= 10.0;
}
// print polarity character
if(negative)
rprintfChar('-');
else
rprintfChar('+');
// print digits
for(i=0; i<numDigits; i++)
{
digit = (x/place);
if(digit | firstplace | (place == 1.0))
{
firstplace = TRUE;
rprintfChar(digit+0x30);
}
else
rprintfChar(' ');
if(place == 1.0)
{
rprintfChar('.');
}
x -= (digit*place);
place /= 10.0;
}
}
#endif
#ifdef RPRINTF_SIMPLE
// *** rprintf1RamRom ***
//! called by rprintf() - does a simple printf (supports %d, %x, %c)
// Supports:
// %d - decimal
// %x - hex
// %c - character
int rprintf1RamRom(unsigned char stringInRom, const char *format, ...)
{
// simple printf routine
// define a global HexChars or use line below
//static char HexChars[16] = "0123456789ABCDEF";
char format_flag;
unsigned int u_val, div_val, base;
va_list ap;
va_start(ap, format);
for (;;)
{
while ((format_flag = READMEMBYTE(stringInRom,format++) ) != '%')
{ // Until '%' or '\0'
if (!format_flag)
{
va_end(ap);
return(0);
}
rprintfChar(format_flag);
}
switch (format_flag = READMEMBYTE(stringInRom,format++) )
{
case 'c': format_flag = va_arg(ap,int);
default: rprintfChar(format_flag); continue;
case 'd': base = 10; div_val = 10000; goto CONVERSION_LOOP;
case 'x': base = 16; div_val = 0x10;
CONVERSION_LOOP:
u_val = va_arg(ap,int);
if (format_flag == 'd')
{
if (((int)u_val) < 0)
{
u_val = - u_val;
rprintfChar('-');
}
while (div_val > 1 && div_val > u_val) div_val /= 10;
}
do
{
rprintfChar(pgm_read_byte(HexChars+(u_val/div_val)));
u_val %= div_val;
div_val /= base;
} while (div_val);
}
}
va_end(ap);
}
#endif
#ifdef RPRINTF_COMPLEX
// *** rprintf2RamRom ***
//! called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s)
// Supports:
// %d - decimal
// %u - unsigned decimal
// %o - octal
// %x - hex
// %c - character
// %s - strings
// and the width,precision,padding modifiers
// **this printf does not support floating point numbers
int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...)
{
register unsigned char *f, *bp;
register long l;
register unsigned long u;
register int i;
register int fmt;
register unsigned char pad = ' ';
int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
int sign = 0;
va_list ap;
va_start(ap, sfmt);
f = (unsigned char *) sfmt;
for (; READMEMBYTE(stringInRom,f); f++)
{
if (READMEMBYTE(stringInRom,f) != '%')
{ // not a format character
// then just output the char
rprintfChar(READMEMBYTE(stringInRom,f));
}
else
{
f++; // if we have a "%" then skip it
if (READMEMBYTE(stringInRom,f) == '-')
{
flush_left = 1; // minus: flush left
f++;
}
if (READMEMBYTE(stringInRom,f) == '0'
|| READMEMBYTE(stringInRom,f) == '.')
{
// padding with 0 rather than blank
pad = '0';
f++;
}
if (READMEMBYTE(stringInRom,f) == '*')
{ // field width
f_width = va_arg(ap, int);
f++;
}
else if (Isdigit(READMEMBYTE(stringInRom,f)))
{
f_width = atoiRamRom(stringInRom, (char *) f);
while (Isdigit(READMEMBYTE(stringInRom,f)))
f++; // skip the digits
}
if (READMEMBYTE(stringInRom,f) == '.')
{ // precision
f++;
if (READMEMBYTE(stringInRom,f) == '*')
{
prec = va_arg(ap, int);
f++;
}
else if (Isdigit(READMEMBYTE(stringInRom,f)))
{
prec = atoiRamRom(stringInRom, (char *) f);
while (Isdigit(READMEMBYTE(stringInRom,f)))
f++; // skip the digits
}
}
if (READMEMBYTE(stringInRom,f) == '#')
{ // alternate form
hash = 1;
f++;
}
if (READMEMBYTE(stringInRom,f) == 'l')
{ // long format
do_long = 1;
f++;
}
fmt = READMEMBYTE(stringInRom,f);
bp = buf;
switch (fmt) { // do the formatting
case 'd': // 'd' signed decimal
if (do_long)
l = va_arg(ap, long);
else
l = (long) (va_arg(ap, int));
if (l < 0)
{
sign = 1;
l = -l;
}
do {
*bp++ = l % 10 + '0';
} while ((l /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (bp - buf);
if (!flush_left)
while (f_width-- > 0)
rprintfChar(pad);
for (bp--; bp >= buf; bp--)
rprintfChar(*bp);
if (flush_left)
while (f_width-- > 0)
rprintfChar(' ');
break;
case 'o': // 'o' octal number
case 'x': // 'x' hex number
case 'u': // 'u' unsigned decimal
if (do_long)
u = va_arg(ap, unsigned long);
else
u = (unsigned long) (va_arg(ap, unsigned));
if (fmt == 'u')
{ // unsigned decimal
do {
*bp++ = u % 10 + '0';
} while ((u /= 10) > 0);
}
else if (fmt == 'o')
{ // octal
do {
*bp++ = u % 8 + '0';
} while ((u /= 8) > 0);
if (hash)
*bp++ = '0';
}
else if (fmt == 'x')
{ // hex
do {
i = u % 16;
if (i < 10)
*bp++ = i + '0';
else
*bp++ = i - 10 + 'a';
} while ((u /= 16) > 0);
if (hash)
{
*bp++ = 'x';
*bp++ = '0';
}
}
i = f_width - (bp - buf);
if (!flush_left)
while (i-- > 0)
rprintfChar(pad);
for (bp--; bp >= buf; bp--)
rprintfChar((int) (*bp));
if (flush_left)
while (i-- > 0)
rprintfChar(' ');
break;
case 'c': // 'c' character
i = va_arg(ap, int);
rprintfChar((int) (i));
break;
case 's': // 's' string
bp = va_arg(ap, unsigned char *);
if (!bp)
bp = (unsigned char *) "(nil)";
f_width = f_width - strlen((char *) bp);
if (!flush_left)
while (f_width-- > 0)
rprintfChar(pad);
for (i = 0; *bp && i < prec; i++)
{
rprintfChar(*bp);
bp++;
}
if (flush_left)
while (f_width-- > 0)
rprintfChar(' ');
break;
case '%': // '%' character
rprintfChar('%');
break;
}
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
sign = 0;
pad = ' ';
}
}
va_end(ap);
return 0;
}
unsigned char Isdigit(char c)
{
if((c >= 0x30) && (c <= 0x39))
return TRUE;
else
return FALSE;
}
int atoiRamRom(unsigned char stringInRom, char *str)
{
int num = 0;;
while(Isdigit(READMEMBYTE(stringInRom,str)))
{
num *= 10;
num += ((READMEMBYTE(stringInRom,str++)) - 0x30);
}
return num;
}
#endif
//******************************************************************************
// code below this line is commented out and can be ignored
//******************************************************************************
/*
char* sprintf(const char *sfmt, ...)
{
register unsigned char *f, *bp, *str;
register long l;
register unsigned long u;
register int i;
register int fmt;
register unsigned char pad = ' ';
int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
int sign = 0;
va_list ap;
va_start(ap, sfmt);
str = bufstring;
f = (unsigned char *) sfmt;
for (; *f; f++)
{
if (*f != '%')
{ // not a format character
*str++ = (*f); // then just output the char
}
else
{
f++; // if we have a "%" then skip it
if (*f == '-')
{
flush_left = 1; // minus: flush left
f++;
}
if (*f == '0' || *f == '.')
{
// padding with 0 rather than blank
pad = '0';
f++;
}
if (*f == '*')
{ // field width
f_width = va_arg(ap, int);
f++;
}
else if (Isdigit(*f))
{
f_width = atoi((char *) f);
while (Isdigit(*f))
f++; // skip the digits
}
if (*f == '.')
{ // precision
f++;
if (*f == '*')
{
prec = va_arg(ap, int);
f++;
}
else if (Isdigit(*f))
{
prec = atoi((char *) f);
while (Isdigit(*f))
f++; // skip the digits
}
}
if (*f == '#')
{ // alternate form
hash = 1;
f++;
}
if (*f == 'l')
{ // long format
do_long = 1;
f++;
}
fmt = *f;
bp = buf;
switch (fmt) { // do the formatting
case 'd': // 'd' signed decimal
if (do_long)
l = va_arg(ap, long);
else
l = (long) (va_arg(ap, int));
if (l < 0)
{
sign = 1;
l = -l;
}
do {
*bp++ = l % 10 + '0';
} while ((l /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (bp - buf);
if (!flush_left)
while (f_width-- > 0)
*str++ = (pad);
for (bp--; bp >= buf; bp--)
*str++ = (*bp);
if (flush_left)
while (f_width-- > 0)
*str++ = (' ');
break;
case 'o': // 'o' octal number
case 'x': // 'x' hex number
case 'u': // 'u' unsigned decimal
if (do_long)
u = va_arg(ap, unsigned long);
else
u = (unsigned long) (va_arg(ap, unsigned));
if (fmt == 'u')
{ // unsigned decimal
do {
*bp++ = u % 10 + '0';
} while ((u /= 10) > 0);
}
else if (fmt == 'o')
{ // octal
do {
*bp++ = u % 8 + '0';
} while ((u /= 8) > 0);
if (hash)
*bp++ = '0';
}
else if (fmt == 'x')
{ // hex
do {
i = u % 16;
if (i < 10)
*bp++ = i + '0';
else
*bp++ = i - 10 + 'a';
} while ((u /= 16) > 0);
if (hash)
{
*bp++ = 'x';
*bp++ = '0';
}
}
i = f_width - (bp - buf);
if (!flush_left)
while (i-- > 0)
*str++ = (pad);
for (bp--; bp >= buf; bp--)
*str++ = ((int) (*bp));
if (flush_left)
while (i-- > 0)
*str++ = (' ');
break;
case 'c': // 'c' character
i = va_arg(ap, int);
*str++ = ((int) (i));
break;
case 's': // 's' string
bp = va_arg(ap, unsigned char *);
if (!bp)
bp = (unsigned char *) "(nil)";
f_width = f_width - strlen((char *) bp);
if (!flush_left)
while (f_width-- > 0)
*str++ = (pad);
for (i = 0; *bp && i < prec; i++)
{
*str++ = (*bp);
bp++;
}
if (flush_left)
while (f_width-- > 0)
*str++ = (' ');
break;
case '%': // '%' character
*str++ = ('%');
break;
}
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
sign = 0;
pad = ' ';
}
}
va_end(ap);
// terminate string with null
*str++ = '\0';
return bufstring;
}
*/

View File

@ -1,135 +0,0 @@
/*! \file rprintf.h \brief printf routine and associated routines. */
//****************************************************************************
//
// File Name : 'rprintf.h'
// Title : printf routine and associated routines
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 2000.12.26
// Revised : 2003.5.1
// Version : 1.0
// Target MCU : Atmel AVR series and other targets
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//****************************************************************************
#ifndef RPRINTF_H
#define RPRINTF_H
// needed for use of PSTR below
#include <avr/pgmspace.h>
// configuration
// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function
// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function
#ifndef RPRINTF_COMPLEX
#define RPRINTF_SIMPLE
#endif
// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat()
// (adds +4600bytes or 2.2Kwords of code)
// defines/constants
#define STRING_IN_RAM 0
#define STRING_IN_ROM 1
// make a putchar for those that are used to using it
//#define putchar(c) rprintfChar(c);
// functions
//! initializes the rprintf library for an output stream
// you must call this initializer once before using any other rprintf function
// the argument must be a single-character stream output function
void rprintfInit(void (*putchar_func)(unsigned char c));
//! prints a single character to the current output device
void rprintfChar(unsigned char c);
//! prints a null-terminated string stored in RAM
void rprintfStr(char str[]);
//! prints a section of a string stored in RAM
// begins printing at position indicated by <start>
// prints number of characters indicated by <len>
void rprintfStrLen(char str[], unsigned int start, unsigned int len);
//! prints a string stored in program rom
// NOTE: this function does not actually store your string in
// program rom, but merely reads it assuming you stored it properly.
void rprintfProgStr(const prog_char str[]);
// Using the function rprintfProgStrM(...) automatically causes
// your string to be stored in ROM, thereby not wasting precious RAM
// Example usage:
// rprintfProgStrM("Hello, this string is stored in program rom");
#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string)))
//! prints a carriage return and line feed
// useful when printing to serial ports/terminals
void rprintfCRLF(void);
// prints the number contained in "data" in hex format
// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively
void rprintfu04(unsigned char data); ///< print 4-bit hex number
void rprintfu08(unsigned char data); ///< print 8-bit hex number
void rprintfu16(unsigned short data); ///< print 16-bit hex number
void rprintfu32(unsigned long data); ///< print 32-bit hex number
//! a flexible integer number printing routine
void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n);
#ifdef RPRINTF_FLOAT
//! floating-point print routine
void rprintfFloat(char numDigits, double x);
#endif
// NOTE: Below you'll see the function prototypes of rprintf1RamRom and
// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions
// of the regular C printf() command. However, they are modified to be able
// to read their text/format strings from RAM or ROM in the Atmel microprocessors.
// Unless you really intend to, do not use the "RamRom" versions of the functions
// directly. Instead use the #defined function versions:
//
// printfx("text/format",args) ...to keep your text/format string stored in RAM
// - or -
// printfxROM("text/format",args) ...to keep your text/format string stored in ROM
//
// where x is either 1 or 2 for the simple or more powerful version of printf()
//
// Since there is much more ROM than RAM available in the Atmel microprocessors,
// and nearly all text/format strings are constant (never change in the course
// of the program), you should try to use the ROM printf version exclusively.
// This will ensure you leave as much RAM as possible for program variables and
// data.
#ifdef RPRINTF_SIMPLE
// a simple printf routine
int rprintf1RamRom(unsigned char stringInRom, const char *format, ...);
// #defines for RAM or ROM operation
#define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args)
#define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args)
// *** Default rprintf(...) ***
// this next line determines what the the basic rprintf() defaults to:
#define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args)
#endif
#ifdef RPRINTF_COMPLEX
// a more powerful printf routine
int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...);
// #defines for RAM or ROM operation
#define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args)
#define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args)
// *** Default rprintf(...) ***
// this next line determines what the the basic rprintf() defaults to:
#define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args)
#endif
#endif

View File

@ -1,102 +0,0 @@
/*! \file avrcore.c \brief AVR-Core Board Driver Functions. */
//*****************************************************************************
//
// File Name : 'avrcore.c'
// Title : AVR-Core Board Driver Functions
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.10.1
// Revised : 2004.10.1
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
//----- Include Files ---------------------------------------------------------
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
#include <avr/signal.h> // include "signal" names (interrupt names)
#include <avr/interrupt.h> // include interrupt support
#include "global.h" // include our global settings
#include "avrcore.h"
// globals
u08 AvrcoreLatch;
// functions
void avrcoreInit(void)
{
// initialize ports to input with pullup
// (this is done to avoid contentions and input-pin oscillation)
outb(DDRA, 0x00);
outb(DDRB, 0x00);
outb(DDRC, 0x00);
outb(DDRD, 0x00);
outb(DDRE, 0x00);
outb(DDRF, 0x00);
outb(PORTA, 0xFF);
outb(PORTB, 0xFF);
outb(PORTC, 0xFF);
outb(PORTD, 0xFF);
outb(PORTE, 0xFF);
outb(PORTF, 0xFF);
// turn on RAM interface
sbi(MCUCR, SRE);
// initialize RAM page
avrcoreSetRamPage(0);
// initialize LEDs
avrcoreSetLeds(0);
// set serial power to on by default
avrcoreSetSerialPortPower(1);
}
void avrcoreSetRamPage(u08 page)
{
// update latch state
AvrcoreLatch &= ~AVRCORELATCH_ADDRMASK;
AvrcoreLatch |= page & AVRCORELATCH_ADDRMASK;
// write new latch state to latch
AVRCORELATCH = AvrcoreLatch;
}
void avrcoreSetLeds(u08 leds)
{
// NOTE: LEDs are negative-logic (active-low)
// update latch state
AvrcoreLatch |= AVRCORELATCH_LEDMASK;
AvrcoreLatch &= ~(leds<<4);
// write new latch state to latch
AVRCORELATCH = AvrcoreLatch;
}
void avrcoreSetLedsOn(u08 leds)
{
// NOTE: LEDs are negative-logic (active-low)
// update latch state to turn on inidicated leds
AvrcoreLatch &= ~(leds<<4);
// write new latch state to latch
AVRCORELATCH = AvrcoreLatch;
}
void avrcoreSetLedsOff(u08 leds)
{
// NOTE: LEDs are negative-logic (active-low)
// update latch state to turn off inidicated leds
AvrcoreLatch |= (leds<<4);
// write new latch state to latch
AVRCORELATCH = AvrcoreLatch;
}
void avrcoreSetSerialPortPower(u08 on)
{
// this function simply manipulates LED3/power control
if(on)
AvrcoreLatch &= ~(0x80);
else
AvrcoreLatch |= (0x80);
// write new latch state to latch
AVRCORELATCH = AvrcoreLatch;
}

View File

@ -1,60 +0,0 @@
/*! \file avrcore.h \brief AVR-Core Board Driver Functions. */
//*****************************************************************************
//
// File Name : 'avrcore.h'
// Title : AVR-Core Board Driver Functions
// Author : Pascal Stang - Copyright (C) 2004
// Created : 2004.10.1
// Revised : 2004.10.1
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef AVRCORE_H
#define AVRCORE_H
// defines and typedefs
#define AVRCORELATCH (*((unsigned char*)0x4000))
#define AVRCORELATCH_ADDRMASK 0x0F
#define AVRCORELATCH_LEDMASK 0xF0
// functions
//! Initialize AVRCore hardware
void avrcoreInit(void);
//! Set the current external RAM page
// The AVRCore on-board external RAM is typically 512KBytes.
// The RAM is memory-mapped into the 32KByte address space from
// 0x8000-0xFFFF, and must therefore be accessed in pages (32KB chunks).
// Use this function to select which of the 16 (0-15) 32KByte pages
// you wish to access.
void avrcoreSetRamPage(u08 page);
//! Set the state of the four LEDs on AVRCore
// leds bit0 => LED1 (0=off, 1=on)
// leds bit1 => LED2 (0=off, 1=on)
// leds bit2 => LED3 (0=off, 1=on)
// leds bit3 => LED4 (0=off, 1=on)
void avrcoreSetLeds(u08 leds);
//! Turn on selected LEDs
// '0' bit = no change
// '1' bit = turn on
void avrcoreSetLedsOn(u08 leds);
//! Turn off selected LEDs
// '0' bit = no change
// '1' bit = turn off
void avrcoreSetLedsOff(u08 leds);
//! Set on/off power setting of AVRCore serial port
// (0=off, 1=on)
void avrcoreSetSerialPortPower(u08 on);
#endif

View File

@ -1,495 +0,0 @@
/*! \file edp.c \brief Emerald Data Protocol System. */
//*****************************************************************************
//
// File Name : 'edp.c'
// Title : Emerald Data Protocol System
// Author : Pascal Stang - Copyright (C) 2003
// Created : 2003.07.01
// Revised : 2003.07.21
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
//----- Include Files ---------------------------------------------------------
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
#include <avr/signal.h> // include "signal" names (interrupt names)
#include <avr/interrupt.h> // include interrupt support
#include <avr/pgmspace.h> // include program-space support
#include "global.h" // include our global settings
#include "i2c.h" // include I2C support
#include "rprintf.h" // include printf function library
#include "edp.h"
// globals
// EDP master/command: response code and reply buffer
u08 EdpCommandResponseCode;
//u08 EdpCommandReplyLength;
u08 EdpCommandReplyBuffer[EDP_REPLY_BUFFER_SIZE];
u08 EdpCommandReplyChecksum;
// EDP slave: response code and reply buffer
u08 EdpSlaveResponseCode;
u08 EdpSlaveReplyLength;
u08 EdpSlaveReplyBuffer[EDP_REPLY_BUFFER_SIZE];
// EDP slave request handler function pointer
EdpSlaveHandlerFuncType edpSlaveHandlerFunc;
// functions
void edpInit(void)
{
// initialize i2c interface and function library
i2cInit();
// set i2c bit rate to 30KHz
i2cSetBitrate(30);
// set the Slave Receive Handler function
// (this function will run whenever a master somewhere else on the bus
// writes data to us as a slave)
i2cSetSlaveReceiveHandler( edpSlaveReceiveService );
// set the Slave Transmit Handler function
// (this function will run whenever a master somewhere else on the bus
// attempts to read data from us as a slave)
i2cSetSlaveTransmitHandler( edpSlaveTransmitService );
}
void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction)
{
edpSlaveHandlerFunc = edpSlaveHandlerFunction;
}
// ************ EDP Master operations ************
u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand)
{
EdpReply* edpCommandReply = (EdpReply*)EdpCommandReplyBuffer;
u08* sendData;
u08* replyData;
u08 replyLength;
u08 checksum;
// initialize response variables
edpCommandReply->Length = 0;
EdpCommandReplyChecksum = 0;
#ifdef EDP_DEBUG
rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR));
#endif
// disable TWI interrupt
cbi(TWCR, TWIE);
// clear TWI interface
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK));
// send start condition
i2cSendStart();
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send device address with write
i2cSendByte( (deviceAddr&0xFE) );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR));
#endif
// check if device is present and live
if( i2cGetStatus() != TW_MT_SLA_ACK)
{
// device did not ACK it's address, command will not continue
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
#ifdef EDP_DEBUG
rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
#endif
// enable TWI interrupt
sbi(TWCR, TWIE);
// return error
return EDP_COMMAND_NODEV;
}
// send data
sendData = (u08*)edpCommand;
checksum = 0;
while(cmdLength)
{
i2cSendByte( *sendData );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR));
#endif
checksum += *sendData++;
cmdLength--;
}
// send the checksum
i2cSendByte( ~checksum );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send repeated start condition
i2cSendStart();
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send device address with read
i2cSendByte( deviceAddr|0x01 );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR));
#endif
// read response code, return NACK
i2cReceiveByte(FALSE);
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR));
#endif
EdpCommandResponseCode = i2cGetReceivedByte();
if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY)
{
// a data reply is being sent
// send repeated start condition
i2cSendStart();
i2cWaitForComplete();
// send device address with read
i2cSendByte( deviceAddr|0x01 );
i2cWaitForComplete();
// get length, return ACK
i2cReceiveByte(TRUE);
i2cWaitForComplete();
edpCommandReply->Length = i2cGetReceivedByte();
// set temp variables
replyLength = edpCommandReply->Length;
replyData = edpCommandReply->Data;
// get data, return ACKs
// preset checksum with the datalength byte
checksum = replyLength;
while(replyLength > 1)
{
i2cReceiveByte(TRUE); // receive data byte and return ACK
i2cWaitForComplete();
*replyData = i2cGetReceivedByte();
checksum += *replyData++;
replyLength--;
}
// get last data (actually the checksum), return NACK (last-byte signal)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*replyData = i2cGetReceivedByte();
// add received checksum+1 to our checksum, the result should be zero
checksum += (*replyData) + 1;
// save the reply checksum
EdpCommandReplyChecksum = checksum;
}
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
#ifdef EDP_DEBUG
rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
#endif
// enable TWI interrupt
sbi(TWCR, TWIE);
return EDP_COMMAND_OK;
}
// get the response code and reply from last command
u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply)
{
u08 retval=EDP_REPLY_OK;
// get the response code from last command
*responseCode = EdpCommandResponseCode;
// get the reply from last command
*edpReply = (EdpReply*)EdpCommandReplyBuffer;
// check response code
if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY)
{
// there was a reply, check the checksum
// if it's non-zero, data corruption is present
if(EdpCommandReplyChecksum)
retval = EDP_REPLY_BADCHKSUM;
}
return retval;
}
/*
u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData)
{
u08* replyData = EdpCommandReplyBuffer;
u08 replyLength;
u08 checksum;
// initialize response variables
EdpCommandReplyLength = 0;
EdpCommandReplyChecksum = 0;
#ifdef EDP_DEBUG
rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR));
#endif
// disable TWI interrupt
cbi(TWCR, TWIE);
// clear TWI interface
//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK));
// send start condition
i2cSendStart();
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send device address with write
i2cSendByte( (deviceAddr&0xFE) );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR));
#endif
// check if device is present and live
if( i2cGetStatus() != TW_MT_SLA_ACK)
{
// device did not ACK it's address, command will not continue
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
#ifdef EDP_DEBUG
rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
#endif
// enable TWI interrupt
sbi(TWCR, TWIE);
// return error
return EDP_COMMAND_NODEV;
}
// send data
checksum = 0;
while(sendLength)
{
i2cSendByte( *sendData );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR));
#endif
checksum += *sendData++;
sendLength--;
}
// send the checksum
i2cSendByte( ~checksum );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send repeated start condition
i2cSendStart();
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR));
#endif
// send device address with read
i2cSendByte( deviceAddr|0x01 );
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR));
#endif
// read response code, return NACK
i2cReceiveByte(FALSE);
i2cWaitForComplete();
#ifdef EDP_DEBUG
rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR));
#endif
EdpCommandResponseCode = i2cGetReceivedByte();
if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY)
{
// a data reply is being sent
// send repeated start condition
i2cSendStart();
i2cWaitForComplete();
// send device address with read
i2cSendByte( deviceAddr|0x01 );
i2cWaitForComplete();
// get length, return ACK
i2cReceiveByte(TRUE);
i2cWaitForComplete();
replyLength = i2cGetReceivedByte();
EdpCommandReplyLength = replyLength;
// get data, return ACKs
// preset checksum with the datalength byte
checksum = replyLength;
while(replyLength > 1)
{
i2cReceiveByte(TRUE); // receive data byte and return ACK
i2cWaitForComplete();
*replyData = i2cGetReceivedByte();
checksum += *replyData++;
replyLength--;
}
// get last data (actually the checksum), return NACK (last-byte signal)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*replyData = i2cGetReceivedByte();
// add received checksum+1 to our checksum, the result should be zero
checksum += (*replyData) + 1;
// save the reply checksum
EdpCommandReplyChecksum = checksum;
}
// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
while( !(inb(TWCR) & BV(TWSTO)) );
#ifdef EDP_DEBUG
rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
#endif
// enable TWI interrupt
sbi(TWCR, TWIE);
return EDP_COMMAND_OK;
}
u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData)
{
u08 retval=EDP_REPLY_OK;
// get the response code and reply data from last command
*responseCode = EdpCommandResponseCode;
// get the reply length from last command
*replyLength = EdpCommandReplyLength;
// get the reply data from last command
*replyData = EdpCommandReplyBuffer;
// check response code
if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY)
{
// there was a reply, check the checksum
// if it's non-zero, data corruption is present
if(EdpCommandReplyChecksum)
retval = EDP_REPLY_BADCHKSUM;
}
return retval;
}
*/
// ************ EDP Slave operations ************
// this function will run when a master somewhere else on the bus
// addresses us and wishes to write data to us
void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData)
{
u08 i,checksum;
// initialize the reply length from this command
EdpSlaveReplyLength = 0;
// verify the checksum
// initialize the checksum with 1
checksum = 0x01;
// sum all the data in the packet and the data's checksum
for(i=0; i<receiveDataLength; i++)
{
checksum += receiveData[i];
}
// if the checksum is non-zero, then the data is corrupt
if(checksum)
{
// set reply code
// [FIX] which should it be?
EdpSlaveResponseCode = EDP_RESP_DATA_CHK_ERROR;
//EdpSlaveResponseCode = EDP_RESP_CMD_CHK_ERROR;
return;
}
// make an EDP command pointer to the received I2C data
EdpCommand* edpCommand = (EdpCommand*)receiveData;
// if a slave handler is defined
if(edpSlaveHandlerFunc)
{
// then use it
EdpSlaveResponseCode = edpSlaveHandlerFunc(
receiveDataLength, edpCommand,
EDP_REPLY_BUFFER_SIZE, (EdpReply*)EdpSlaveReplyBuffer);
}
else
{
// otherwise reply with unknown command
EdpSlaveResponseCode = EDP_RESP_UNKWN_CMD;
}
}
// this function will run when a master somewhere else on the bus
// addresses us and wishes to read data from us
u08 edpSlaveTransmitService(u08 transmitDataLengthMax, u08* transmitData)
{
u08 i;
u08 checksum;
u08 transmitDataLength = 0;
EdpReply* edpReply = (EdpReply*)EdpSlaveReplyBuffer;
if(EdpSlaveResponseCode)
{
// reply code is non-zero, we must send it
*transmitData = EdpSlaveResponseCode;
transmitDataLength = 1;
// reset the reply code to flag that we've sent it
EdpSlaveResponseCode = 0;
}
else
{
// reply code already sent, now send data (if any)
// copy length of reply to transmit buffer (+1 for checksum)
*transmitData++ = edpReply->Length+1;
// initialize checksum
checksum = edpReply->Length+1;
// copy reply buffer to the transmit buffer
for(i=0; i<edpReply->Length; i++)
{
*transmitData++ = edpReply->Data[i];
checksum += edpReply->Data[i];
}
// copy checksum to transmit buffer
*transmitData++ = ~checksum;
// set number of bytes to transmit
transmitDataLength = edpReply->Length+2;
}
// return number of bytes written to transmit buffer
return transmitDataLength;
}

Some files were not shown because too many files have changed in this diff Show More