Compare commits

...

10 commits

Author SHA1 Message Date
stephan
46e0ebda74 arm/avr: move to git https://forge.bexus.org/Stephan/irena-avr
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9095 bc5caf13-1734-44f8-af43-603852e9ee25
2024-09-03 12:13:18 +00:00
chaos
86b3b52126 CHAOS SPY: lower sane Temp limit, fix spy script closing
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9094 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-26 15:58:14 +00:00
chaos
bf9f238b0c CHAOS/IRENA.RC: disable l2t[0]
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9093 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-26 15:56:35 +00:00
chaos
50263b9cc2 CHAOS/SAFE.RC: fix echo syntax
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9092 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-26 15:55:54 +00:00
stephan
d06e324d55 flash_CHAOS: typo in IP address :-(
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9091 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-26 15:39:02 +00:00
stephan
19192ec206 CHAOS/ETH.RC: flight config
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9090 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-24 11:19:16 +00:00
stephan
6ebc588ecd IRENA: CHAOS HK fix T9, add T12
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9089 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-02 08:21:53 +00:00
stephan
af21d0066e IRENA: CHAOS HK
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9088 bc5caf13-1734-44f8-af43-603852e9ee25
2024-08-02 08:17:13 +00:00
chaos
d392a69c06 CHAOS: ETH.RC: etsolo1
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9087 bc5caf13-1734-44f8-af43-603852e9ee25
2024-07-29 08:30:34 +00:00
chaos
e064002e15 CHAOS: Anpassung von Triggerschwellen + Aenderung L2 Trigger
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm@9086 bc5caf13-1734-44f8-af43-603852e9ee25
2024-07-29 07:39:49 +00:00
52 changed files with 63 additions and 6950 deletions

View file

@ -1,388 +0,0 @@
/*
* ECRIS_REMOTE.c
*
* Created: 11.05.2012 15:54:25
* Author: Lauri
*
* PinAssignements:
* 0 1 2 3 4 5 6 7
*
* PA: Vref - DAC0 DAC1 - - ADC6 ADC7
* PC: IP1 IP2 IP3 IP4 - - - - IP = Identification Pin
* PE: - - RXD0 TXD0 - - - -
* PF: - - - RY1 RY2 RY3 RY4 RY5 RY = Relay
* PH: Pin1 Pin2 Pin3 Pin4 Pin5 Pin6 Pin7 Pin8 Pins of DSub15
* PJ: Pin9 Pin10 Pin11 Pin12 - - - - Pins of DSub15
* PR: XTAL1 XTAL0 - - - - - - oscillator
*
*/
#define F_CPU 11059200
#define H "iS" // header for "ion Source"
#define error_illegal_cmd 0xf0
#define error_illegal_id 0xf1
#include <avr/io.h>
// port pin directions:
#define PORTA_DACs 0b00001100
#define PORTF_RYs 0b11111000
#define PORTH_DSUB_1 0b11111111
#define PORTJ_DSUB_2 0b00001111
//******************************************************************
static
void clock_init(void)
{ // use external oscillator at 11059200Hz
PORTR.DIR = 0b11111111; // all PortR is output
CLK.PSCTRL = 0b00000000; // Prescaler 1
OSC.XOSCCTRL |= (OSC_FRQRANGE_9TO12_gc | OSC_XOSCSEL_XTAL_256CLK_gc); // sets start-up time and selects frequency range
OSC.CTRL = OSC_XOSCEN_bm; // external oscillator enable
while ((OSC.STATUS & OSC_XOSCRDY_bm) == 0); // wait until oscillator is stable
CCP = CCP_IOREG_gc; // configuration change protection p 12
CLK.CTRL = CLK_SCLKSEL_XOSC_gc; // uses external osc or clk
OSC.CTRL &= ~( OSC_RC2MEN_bm ); // disable internal clock
// only for testing:
//PORTD.DIR = 0b10000000; // sets PD7 as output
//PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PD7_gc; // peripheral clock output on pin PD7
}
static
void init_USART(void)
{ // USARTE0, 19200baud, 8 Data bits, No Parity, 1 Stop bit.
PORTE.DIRSET = PIN3_bm; // TXD
PORTE.DIRCLR = PIN2_bm; // RXD
USARTE0.BAUDCTRLA = 0b00001000; // set baud-rate (BSEL 8lsb)
USARTE0.BAUDCTRLB = 0b00100000; // set baud-rate (BSCALE | BSEL) 4bit each, 4msb for BSEL
USARTE0.CTRLA = 0; // no interrupts
USARTE0.CTRLC = 0b00000011; // 8N1
USARTE0.CTRLB = 0b00011000; // enable receiver and transmitter
}
static
void init_ADCs(void)
{
PORTA.DIR = PORTA_DACs; // ADCs are inputs (and therefore =0)
// Aref !< Vcc- 0.6V!! we use INTVCC (Vcc/1.6)
ADCA.CTRLA = ADC_ENABLE_bm; // enable adc
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; // 12 bit conversion
ADCA.REFCTRL = ADC_REFSEL_AREFA_gc; // external AREF reference on PinA0 (max VCC-0.6V!!)
ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc; // peripheral clk/512 (11059200Hz/512=21600Hz)
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; // single ended input, no gain
}
static inline
uint16_t get_voltage_ADC_A0(void)
{
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; // PORTA:0
ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
while(!ADCA.CH0.INTFLAGS); // wait until ready
uint16_t ADC_A0_RES = ADCA.CH0RES; //12bit ADC result
ADC_A0_RES = 0;
uint8_t mA0;
uint32_t reading_A0 = 0;
for (mA0=0;mA0<128;mA0++)
{
ADCA.CH0.CTRL |= ADC_CH_START_bm; // start conversion on channel 0
while(!ADCA.CH0.INTFLAGS); // wait until ready
reading_A0 += ADCA.CH0RES; //12bit ADC result
}
ADC_A0_RES = (reading_A0 / 128);
return ADC_A0_RES;
}
static
uint16_t get_voltage_ADC_A1(void)
{
ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc; // PORTA:1
ADCA.CH1.CTRL |= ADC_CH_START_bm; // start conversion on channel 1
while(!ADCA.CH1.INTFLAGS); // wait until ready
uint16_t ADC_A1_RES = ADCA.CH1RES; //12bit ADC result
ADC_A1_RES = 0;
uint8_t mA1;
uint32_t reading_A1 = 0;
for (mA1=0;mA1<128;mA1++)
{
ADCA.CH1.CTRL |= ADC_CH_START_bm; // start conversion on channel 1
while(!ADCA.CH1.INTFLAGS); // wait until ready
reading_A1 += ADCA.CH1RES; //12bit ADC result
}
ADC_A1_RES = (reading_A1 / 128);
return ADC_A1_RES;
}
static
void init_DACs(void)
{
PORTA.DIR = PORTA_DACs; // ADCs are inputs (and therefore =0)
// Aref !< Vcc- 0.6V!! (use 2,5V)
DACA.CTRLA |= (DAC_CH0EN_bm | DAC_CH1EN_bm | DAC_ENABLE_bm); // allows DAC-values at output pins and enables DAC
DACA.CTRLB = DAC_CHSEL_DUAL_gc; // uses both channels as standard with Sample/Hold
DACA.CTRLC = DAC_REFSEL_AREFA_gc; // same VREF as for ADCs
DACA.TIMCTRL |= (DAC_CONINTVAL_128CLK_gc | DAC_REFRESH_OFF_gc);
// DAC conversion interval (128 means 192clks in dual mode); auto-refreshing of the outputs disabled
}
static inline
uint16_t set_voltage_DAC_01(uint16_t val)
{
DACA.CH0DATA = val;
while ( !(DACA.STATUS & (1 << 0b00000001)) ) ;
return DACA.CH0DATA;
}
static inline
uint16_t set_voltage_DAC_02(uint16_t val)
{
DACA.CH1DATA = val;
while ( !(DACA.STATUS & (1 << 0b00000010)) ) ;
return DACA.CH1DATA;
}
static inline
void uart_putchar(char c)
{
USARTE0.DATA = c; // Put our character into the transmit buffer
while ( !( USARTE0.STATUS & USART_DREIF_bm) ); // Wait for the transmit buffer to be empty
}
static inline
unsigned char uart_getchar()
{
while ((USARTE0.STATUS & USART_RXCIF_bm) == 0); // wait until data received
return USARTE0.DATA;
}
static
void return_command(unsigned char com, uint16_t val)
{ // gives back header in wrong order, the command bit, the value bits, and a checksum
uart_putchar(H[1]);
uart_putchar(H[0]);
uart_putchar(com);
uart_putchar(val&0xff);
uart_putchar(val>>8);
uart_putchar(H[0]^H[1]^com^(val&0xff)^(val>>8)); // calculation of the checksum
}
//******************************************************************
static inline
uint8_t set_microwave(uint16_t val)
{ // 5 bit max, LSB = F3, MSB = F7
PORTF.DIR = PORTF_RYs; // setting relays as output
PORTF.OUTSET = (val * 8);
return (PORTF_IN / 8);
}
static inline
uint8_t read_microwave_inputs()
{
PORTF.DIR = PORTF_RYs; // setting relays as output
return (PORTF_IN / 8); // check relays configuration
}
static inline
uint16_t read_microwave_outputs()
{
PORTH.DIR &= ~(PORTH_DSUB_1); // setting DSub-connector as input
PORTJ.DIR &= ~(PORTJ_DSUB_2); // setting DSub-connector as input
uint8_t DSUB15_L = PORTH_IN; // read digital status
uint8_t DSUB15_H = PORTJ_IN;
uint16_t DSUB15 = (DSUB15_L + (DSUB15_H * 256));
return DSUB15;
}
static inline
uint16_t set_uw_attenuator(uint16_t val)
{ // writes DSUB15 (12 bit max) to the pins of the DSub15 connector
PORTH.DIR = PORTH_DSUB_1; // setting DSub-connector as output
PORTJ.DIR = PORTJ_DSUB_2; // setting DSub-connector as output
uint8_t DSUB15_L = (val % 256);
uint8_t DSUB15_H = (val / 256);
PORTH.OUTSET = DSUB15_L;
PORTJ.OUTSET = DSUB15_H;
DSUB15_L = PORTH_IN; // read digital status
DSUB15_H = PORTJ_IN;
uint16_t DSUB15 = (DSUB15_L + (DSUB15_H * 256));
return DSUB15;
}
static inline
uint16_t read_uw_attenuator()
{
PORTH.DIR = PORTH_DSUB_1; // setting DSub-connector as output
PORTJ.DIR = PORTJ_DSUB_2; // setting DSub-connector as output
uint8_t DSUB15_L = PORTH_IN; // read digital status
uint8_t DSUB15_H = PORTJ_IN;
uint16_t DSUB15 = (DSUB15_L + (DSUB15_H * 256));
return DSUB15;
}
static inline
uint16_t set_gasventile_1(uint16_t val)
{
return set_voltage_DAC_01(val);
}
static inline
uint16_t read_gasventile_1()
{
return get_voltage_ADC_A0();
}
static inline
uint16_t set_gasventile_2(uint16_t val)
{
return set_voltage_DAC_02(val);
}
static inline
uint16_t read_gasventile_2()
{
return get_voltage_ADC_A1();
}
static inline
uint16_t set_HVecr(uint16_t val)
{
return set_voltage_DAC_01(val);
}
static inline
uint16_t read_HVecr()
{
return get_voltage_ADC_A0();
}
static inline
uint16_t set_HVrep(uint16_t val)
{
set_voltage_DAC_01(val);
return 0;
}
static inline
uint16_t read_HVrep()
{
return get_voltage_ADC_A0();
}
static inline
uint16_t set_HVlens(uint16_t val)
{
return set_voltage_DAC_01(val);
}
static inline
uint16_t read_HVlens()
{
return get_voltage_ADC_A0();
}
//******************************************************************
static
void get_command() // 6byte commands: 2byte header, 1byte command, 2byte value, 1byte checksum
{
PORTC.DIR = 0b00000000; // all PortC is input
// 0: microwave given by the hardware switch onboard!!
// 1: uw_attenuator
// 2: gasventile
// 3: HVecr
// 4: HVrep
// 5: HVlens
uint8_t identifier = (PORTC_IN & 0xf); // 4 LSB of PortC
unsigned char b = uart_getchar(); // header1
while (b==H[0]) {
unsigned char p = b;
b = uart_getchar();
if (b!=H[1]) continue; // header2
p ^= b;
unsigned char com = uart_getchar(); // command
p ^= com;
b = uart_getchar(); // value 8lsb
p ^= b;
uint16_t val = b;
b = uart_getchar(); // value 8msb
p ^= val;
val |= b<<8;
b = uart_getchar(); // p is checksum
p ^= b;
if (p) continue; // checksum must give 0!
switch (identifier) {
case 0: // microwave
switch (com) {
case 0x00: return_command(com, set_microwave(val)); break;
case 0x01: return_command(com, read_microwave_inputs()); break;
case 0x02: return_command(com, read_microwave_outputs()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
case 1: // uw_attenuator
switch (com) {
case 0x10: if (identifier == 1) return_command(com, set_uw_attenuator(val)); break;
case 0x11: if (identifier == 1) return_command(com, read_uw_attenuator()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
case 2: // gasventile
switch (com) {
case 0x20: if (identifier == 2) return_command(com, set_gasventile_1(val)); break;
case 0x21: if (identifier == 2) return_command(com, read_gasventile_1()); break;
case 0x28: if (identifier == 2) return_command(com, set_gasventile_2(val)); break;
case 0x29: if (identifier == 2) return_command(com, read_gasventile_2()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
case 3: // HVecr
switch (com) {
case 0x30: if (identifier == 3) return_command(com, set_HVecr(val)); break;
case 0x31: if (identifier == 3) return_command(com, read_HVecr()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
case 4: // HVrep
switch (com) {
case 0x40: if (identifier == 4) return_command(com, set_HVrep(val)); break;
case 0x41: if (identifier == 4) return_command(com, read_HVrep()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
case 5: // HVlens
switch (com) {
case 0x50: if (identifier == 5) return_command(com, set_HVlens(val)); break;
case 0x51: if (identifier == 5) return_command(com, read_HVlens()); break;
default: return_command(error_illegal_cmd, com | (identifier << 8));
}
break;
default:
return_command(error_illegal_id, com | (identifier << 8));
}
}
}
int main (void)
{
clock_init();
init_USART();
init_ADCs();
init_DACs();
while (1)
get_command();
return 0;
}

View file

@ -1,432 +0,0 @@
# Hey Emacs, this is a -*- makefile -*-
#
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
# Released to the Public Domain
# Please read the make user manual!
#
# Additional material for this makefile was submitted by:
# Tim Henigan
# Peter Fleury
# Reiner Patommel
# Sander Pool
# Frederik Rouleau
# Markus Pfaff
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
#
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# 4.07 or greater).
#
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only
#
# To rebuild project do "make clean" then "make all".
#
# MCU name
MCU = atmega128
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = main
# clock frequency
F_CPU = 11059200
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
SRC += iodriver/avr/avr_uart.c
#SRC += lcd_routines.c
#SRC += iodriver/mini_atmega_testboard.c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS =
# Place -I options here
CINCS =
# Compiler flags.
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes -Wmissing-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
CFLAGS += -pedantic
# Assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
#Additional libraries.
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
SCANF_LIB =
MATH_LIB = -lm
# External memory options
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x808000,--defsym=__heap_end=0x80ffff
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x802000,--defsym=__heap_end=0x809fff
#EXTMEMOPTS = -Wl,-Tdata=0x802000,--defsym=__heap_end=0x809fff
EXTMEMOPTS =
# Linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
# Programming support using avrdude. Settings and variables.
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkii
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
# ---------------------------------------------------------------------------
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) -DF_CPU=$(F_CPU)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter finished end
build: elf hex eep lss sym
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
finished:
@echo $(MSG_ERRORS_NONE)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program:
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# STK500 -cUSB -d$(MCU) -e -if$(TARGET).hex -pf -vf -I2000000
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program

View file

@ -1,541 +0,0 @@
#include <avr/io.h>
#include <avr/signal.h>
#include "iodriver/avr/avr_uart.h"
/*****************************************************************************
Name: UART_Init
Description: intizialization of UART according to processortype
(__AVR_ATmega8__ | __AVR_ATmega16__ | __AVR_ATmega32__ |
__AVR_ATmega64__ | __AVR_ATmega163__ | __AVR_ATmega128__ |
__AVR_AT90CAN128__)
Parameters: unsigned char UARTNr UART0(0x00) or UART1(0x01)
unsigned long BaudrateValue i.e. 115200 or 9600
char databits 5 to 9
char parity 0 = no parity
1 = odd parity
2 = even parity
char stopbit 1 or 2
Returns: 0x00 no error, no warning
0x01 invalid UART-Number setting
0x02 invalid number of databits
0x04 invalid parity setting
0x08 invalid number of stopbits
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_Init(unsigned char UARTNr, unsigned long Baudrate, char databits, char parity, char stopbit)
{
int error = 0x00;
unsigned char csra_value=0;
unsigned char csrb_value=0;
unsigned char csrc_value=0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
// check off invalid parameters
if((databits < 5) || (databits > 9))
{
error = 0x02;
}
else if((parity+1 < UART_NoParity+1) || (parity+1 > UART_OddParity+1)) // +1 bypass "warning message" with equation "x < 0"
{
error = 0x04;
}
else if((stopbit < 1) || (stopbit > 2))
{
error = 0x08;
}
else // all parameters in a valid range
{
// setting of uart transmission speed (single)
csra_value &= ~(1 << U2X);
// baud rate register setting
if (databits < 9)
{
csrc_value |= ((databits-5) << 1);
}
else
{
csrc_value |= 0x06;
csrb_value |= 0x04;
}
// setting chosen parity-mode
csrc_value |= parity << 4;
// setting number of chosen stopbit(s)
csrc_value |= ((stopbit-1)<<3);
// enables receiver and transmitter
csrb_value |= ((1 << TXEN) | (1 << RXEN));
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UBRR0H = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRR0L = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSR0A = csra_value;
UCSR0B = csrb_value;
UCSR0C = csrc_value;
clearBit(DDRE,0); // UART RxD
setBit(DDRE,1); // UART TxD
setBit(PORTE,1); // UART TxD
}
else
{
UBRR1H = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRR1L = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSR1A = csra_value;
UCSR1B = csrb_value;
UCSR1C = csrc_value;
clearBit(DDRD,2); // UART RxD
setBit(DDRD,3); // UART TxD
setBit(PORTD,3); // UART TxD
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
UBRRH = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRRL = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSRA = csra_value;
UCSRB = csrb_value;
UCSRC = 0x80 | csrc_value;
clearBit(DDRD,0); // UART RxD
setBit(DDRD,1); // UART TxD
setBit(PORTD,1); // UART TxD
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*****************************************************************************
Name: UART_WriteChar
Description: transmit char via UART
Parameters: unsigned char UARTNr UART0 or UART1
char AChar char to transmit
Returns: 0x00 no error, no warning
0x01 ERROR
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_WriteChar(unsigned char UARTNr, char AChar)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if(UARTNr > 1)
{
error = TRUE;
}
else
{
if(UARTNr==0)
{
while(bit_is_clear(UCSR0A,UDRE0));
UDR0=AChar;
}
else
{
while(bit_is_clear(UCSR1A,UDRE1)); //while(!(UCSR1A & (1<<UDRE1)));
UDR1=AChar;
}
}
#else
if(UARTNr != 0)
{
error = TRUE;
}
else
{
while(bit_is_clear(UCSRA,UDRE));
UDR=AChar;
}
#endif
return(error);
}
/*****************************************************************************
Name: UART_WriteString
Description: transmit string via UART
Parameters: unsigned char UARTNr UART0 or UART1
char * AString pointer to string
Returns: 0x00 no error
0x01 error in uartnumber
0x02 string is empty
0x03 error while UART_WriteChar
0x04 string to transmit is greater than length of integer
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_WriteString(unsigned char UARTNr, char *AString)
{
unsigned int n = 0;
unsigned char TxChar;
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if(UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
TxChar = AString[0];
if(TxChar==0)
{
error = 0x02;
}
else
{
do
{
if(UART_WriteChar(UARTNr,TxChar))
{
error = 0x03;
}
if(++n == 0)
{
error = 0x04;
}
TxChar = AString[n];
}
while((TxChar != 0) && (error == 0));
}
}
return(error);
}
/*****************************************************************************
Name: UART_ReceiveChar
Description: receive a char via UART
Attention: Functions waits in while-loop until a char received
Parameters: unsigned char UARTNr UART0 or UART1
char *rx_byte pointer to char
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_ReceiveChar(unsigned char UARTNr, char *rx_byte)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
else
{
if (UARTNr==0)
{
while(!(UCSR0A & (1<<RXC0)));
*rx_byte = UDR0;
}
else
{
while(!(UCSR1A & (1<<RXC1)));
*rx_byte = UDR1;
}
}
#else
if(UARTNr != 0)
{
error = 0x01;
}
else
{
while (!(UCSRA & (1<<RXC))); // wait till char is available
*rx_byte = UDR;
}
#endif
return(error);
}
/*****************************************************************************
Name: UART_EnableRxInt
Description: enable Rx Interrupt
Parameters: unsigned char UARTNr UART0 or UART1
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_EnableRxInt(unsigned char UARTNr)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UCSR0B |= (1 << RXCIE0);
}
else
{
UCSR1B |= (1 << RXCIE1);
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
if (UARTNr==UART0)
{
UCSRB |= (1 << RXCIE);
}
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*****************************************************************************
Name: UART_DisableRxInt
Description: enable Rx Interrupt
Parameters: unsigned char UARTNr UART0 or UART1
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_DisableRxInt(unsigned char UARTNr)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UCSR0B &= ~(1 << RXCIE0);
}
else
{
UCSR1B &= ~(1 << RXCIE1);
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
if (UARTNr==UART0)
{
UCSRB &= ~(1 << RXCIE);
}
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
SIGNAL(SIG_UART0_RECV)
{
unsigned char c;
c = UDR0;
}
SIGNAL(SIG_UART1_RECV)
{
unsigned char c;
c = UDR1;
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
SIGNAL(SIG_UART_RECV)
{
unsigned char c;
c = inp(UDR);
}
#endif
*/
/*****************************************************************************
Functionname: *UART_ReceiveString
Functiondescription: receive a string via UART with
this functions waits until a char received
function endswhen <CR> or <LF> received
Parameters: unsigned char UARTNr UART0 or UART1
char *s string to copy received string
unsigned char charmax number of max char to receive
Returns: char *s received string
******************************************************************************
03. 05. 2006 BSH
******************************************************************************
Changes:
******************************************************************************
char *UART_ReceiveString(unsigned char UARTNr, char *s, unsigned char charmax)
{
unsigned char c;
char *cs;
cs = s; // copy string in a new string
while(charmax > 1)
{
charmax--;
c = UART_ReceiveChar(UARTNr);
if(c == 0x08) // if Backspace
{
if(cs > s)
{
UART_WriteChar(UARTNr, ' ');
UART_WriteChar(UARTNr, 0x08);
cs--;
charmax++;
charmax++;
}
else
{
//UART_WriteChar(UARTNr, ' ');
// arrow key right
UART_WriteChar(UARTNr, 0x1B);
UART_WriteChar(UARTNr, 0x5B);
UART_WriteChar(UARTNr, 0x43);
charmax++;
}
}
else
{
if (( c == 0x0D ) || ( c == 0x0A )) // if "carriage Return" or "Line Feed"
//if ( c == 0x0D ) // if "carriage Return"
{
charmax = 0;
}
else
{
*cs = c;
cs++;
}
}
}
*cs = '\0'; // close a String with NULL
return(s);
}
*/
/*****************************************************************************
Functionname: UART_TransmitHex
Example UART_TransmitHex('B');
Output 0x42
******************************************************************************
03. 05. 2006 BSH
******************************************************************************
Changes:
******************************************************************************
int UART_TransmitHex(unsigned char UARTNr, char s)
{
unsigned char x = 0;
x = (s & 0xF0);
x = x >> 4;
if (UART_WriteChar(UARTNr, '0')) {return(TRUE);}
if (UART_WriteChar(UARTNr, 'x')) {return(TRUE);}
if(x < 10)
{
if (UART_WriteChar(UARTNr, (0x30 + x))) {return(TRUE);}
}
else
{
if (UART_WriteChar(UARTNr, (0x37 + x))) {return(TRUE);}
}
x = (s & 0x0F);
if(x < 10)
{
if (UART_WriteChar(UARTNr, (0x30 + x))) {return(TRUE);}
}
else
{
if (UART_WriteChar(UARTNr, (0x37 + x))) {return(TRUE);}
}
return(FALSE);
}
*/

View file

@ -1,42 +0,0 @@
#ifndef _AVR_UART_H_
#define _AVR_UART_H_
#ifndef F_CPU
#define F_CPU 11059200
#endif
#ifndef MCU
#define MCU atmega32
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#ifndef setBit
#define setBit(PORT, BITNUM) ((PORT) |= (1<<(BITNUM)))
#define clearBit(PORT, BITNUM) ((PORT) &= ~(1<<(BITNUM)))
#define toggleBit(PORT, BITNUM) ((PORT) ^= (1<<(BITNUM)))
#define nop() __asm__ __volatile__ ("nop" ::)
#endif
#define UART0 0
#define UART1 1
#define UART_NoParity 1
#define UART_EvenParity 2
#define UART_OddParity 3
#define UART_BAUD_CALC(UART_BAUD_RATE) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
int UART_Init(unsigned char UARTNr, unsigned long Baudrate, char databits, char parity, char stopbit);
int UART_WriteChar(unsigned char UARTNr, char AChar);
int UART_WriteString(unsigned char UARTNr,char *AString);
int UART_ReceiveChar(unsigned char UARTNr, char *rx_byte);
int UART_EnableRxInt(unsigned char UARTNr);
int UART_DisableRxInt(unsigned char UARTNr);
#endif // _AVR_UART_H_

View file

@ -1,12 +0,0 @@
#include <avr/io.h>
#include "avr/sfr_defs.h"
#include "main.h"
#include "iodriver/mini_atmega_testboard.h"
int init_mini_atmega_testboard(void)
{
DDRC |= 0x1C; /* LED 0 - 2 outputs */
return(FALSE);
}

View file

@ -1,52 +0,0 @@
#ifndef MINI_ATMEGA_TESTBOARD_H
#define MINI_ATMEGA_TESTBOARD_H
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef setBit
#define setBit(PORT, BITNUM) ((PORT) |= (1<<(BITNUM)))
#define clearBit(PORT, BITNUM) ((PORT) &= ~(1<<(BITNUM)))
#define toggleBit(PORT, BITNUM) ((PORT) ^= (1<<(BITNUM)))
#endif
#define LED_2_PORT PORTC
#define LED_1_PORT PORTC
#define LED_0_PORT PORTC
#define LED_2_BIT PIN4
#define LED_1_BIT PIN3
#define LED_0_BIT PIN2
#define T3_PIN PINC
#define T4_PIN PINC
#define T3_BIT PIN1
#define T4_BIT PIN2
#define LED_2_ON() clearBit(LED_2_PORT, LED_2_BIT)
#define LED_2_OFF() setBit(LED_2_PORT, LED_2_BIT)
#define LED_1_ON() clearBit(LED_1_PORT, LED_1_BIT)
#define LED_1_OFF() setBit(LED_1_PORT, LED_1_BIT)
#define LED_0_ON() clearBit(LED_0_PORT, LED_0_BIT)
#define LED_0_OFF() setBit(LED_0_PORT, LED_0_BIT)
#define TOGGLE_LED_2() toggleBit(LED_2_PORT, LED_2_BIT)
#define TOGGLE_LED_1() toggleBit(LED_1_PORT, LED_1_BIT)
#define TOGGLE_LED_0() toggleBit(LED_0_PORT, LED_0_BIT)
#define WAIT_UNTIL_T3_PUSHED() loop_until_bit_is_clear(T3_PIN, T3_BIT)
#define WAIT_UNTIL_T4_PUSHED() loop_until_bit_is_clear(T4_PIN, T4_BIT)
#define T3_PUSHED() bit_is_clear(T3_PIN, T3_BIT)
#define T4_PUSHED() bit_is_clear(T4_PIN, T4_BIT)
int init_mini_atmega_testboard(void);
#endif

View file

@ -1,228 +0,0 @@
#include <avr/io.h>
#include <avr/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "main.h"
#include "iodriver/avr/avr_uart.h"
char S[80] = "\0";
int main(void)
{
unsigned char address;
unsigned char transfervalues[100];
unsigned char returnvalues[4] = {0x00};
avr_init();
UART_WriteString(0, "\nI'm the lcd_master program.\n");
LCDSPI_SendCommand(0x01, &transfervalues[0]); // clear Display
LCDSPI_WriteLetter('h', &transfervalues[4]);
LCDSPI_WriteLetter('a', &transfervalues[8]);
LCDSPI_WriteLetter('l', &transfervalues[12]);
LCDSPI_WriteLetter('l', &transfervalues[16]);
LCDSPI_WriteLetter('o', &transfervalues[20]);
address = LCDSPI_GetAddress(&transfervalues[24]);
//sprintf(S,"Address: %u", address);
//UART_WriteString(0, S);
LCDSPI_MoveCursor(16, &transfervalues[28]);
LCDSPI_WriteString("TEST?!?");
address = LCDSPI_GetAddress(&transfervalues[32]);
//sprintf(S, "Address: %u...", address);
//UART_WriteString(0, S);
address = LCDSPI_GetRamContent(&transfervalues[36]);
//sprintf(S, "RAM-Content:%u", address);
//UART_WriteString(0, S);
define_symbol(0, 0x0E,0x11, 0x0E, 0x04, 0x1F, 0x04,0x0A, 0x11);
define_symbol(1, 0x00,0x0A, 0x1B, 0x1F, 0x0E, 0x04,0x04, 0x00);
LCDSPI_WriteLetter(' ', &transfervalues[40]);
LCDSPI_WriteLetter(0x00, &transfervalues[44]);
LCDSPI_WriteLetter(0x01, &transfervalues[48]);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
_delay_ms(200);
LCDSPI_WriteLetter('!', &transfervalues[64]);
//LCDSPI_SendCommand(0x01, &transfervalues[68]);
while(1);
return(FALSE);
} // END MAIN
int define_symbol(uint8_t symbol_no, uint8_t line0, uint8_t line1, uint8_t line2, uint8_t line3,uint8_t line4, uint8_t line5, uint8_t line6, uint8_t line7)
{
unsigned char empty_array[2];
char str[2];
if (symbol_no > 7)
return(0);
else
{
uint8_t returnaddr = 0;
returnaddr = LCDSPI_GetAddress(empty_array);
sprintf(str,"%u", returnaddr); // without this, we have a bug... why? nobody knows
returnaddr &= ~(1<<7);
LCDSPI_SendCommand(0x38, empty_array);
uint8_t temp = 0;
temp = 0x40 + symbol_no * 8;
LCDSPI_SendCommand(temp, empty_array);
LCDSPI_WriteLetter(line0, empty_array);
LCDSPI_WriteLetter(line1, empty_array);
LCDSPI_WriteLetter(line2, empty_array);
LCDSPI_WriteLetter(line3, empty_array);
LCDSPI_WriteLetter(line4, empty_array);
LCDSPI_WriteLetter(line5, empty_array);
LCDSPI_WriteLetter(line6, empty_array);
LCDSPI_WriteLetter(line7, empty_array);
LCDSPI_SendCommand(0x39, empty_array);
returnaddr |= (1<<7);
LCDSPI_SendCommand(returnaddr, empty_array);
return(1);
}
}
void LCDSPI_WriteString(char *str)
{
unsigned char i = 0;
unsigned char empty_array[2];
for(i=0; i<strlen(str);i++)
{
LCDSPI_WriteLetter(str[i],empty_array);
}
}
unsigned char LCDSPI_MoveCursor(unsigned char addr, unsigned char *retvalues)
{
if (addr < 32)
{
do
{
PORTB &= ~(1<<PB0);
retvalues[0] = TransferByteSPI(0x83);
retvalues[1] = TransferByteSPI(addr);
spi_master_Rx_sync(&retvalues[2]);
PORTB |= (1<<PB0);
}while(retvalues[2] == 0xff);
return(1);
}
else
return(0);
}
unsigned char LCDSPI_GetAddress(unsigned char *retvalues)
{
do
{
PORTB &= ~(1<<PB0);
retvalues[0] = TransferByteSPI(0x86);
retvalues[1] = TransferByteSPI(0x00);
spi_master_Rx_sync(&retvalues[2]);
PORTB |= (1<<PB0);
}while(retvalues[2] == 0xff);
return(retvalues[3]);
}
unsigned char LCDSPI_GetRamContent(unsigned char *retvalues)
{
do
{
PORTB &= ~(1<<PB0);
retvalues[0] = TransferByteSPI(0x87);
retvalues[1] = TransferByteSPI(0x00);
spi_master_Rx_sync(&retvalues[2]);
PORTB |= (1<<PB0);
}while(retvalues[2] == 0xff);
return(retvalues[3]);
}
void LCDSPI_SendCommand(unsigned char cmd, unsigned char *retvalues)
{
do
{
PORTB &= ~(1<<PB0);
retvalues[0] = TransferByteSPI(0x84);
retvalues[1] = TransferByteSPI(cmd);
spi_master_Rx_sync(&retvalues[2]);
PORTB |= (1<<PB0);
}while(retvalues[2] == 0xff);
}
void LCDSPI_WriteLetter(unsigned char letter, unsigned char *retvalues)
{
do
{
PORTB &= ~(1<<PB0);
retvalues[0] = TransferByteSPI(0x85);
retvalues[1] = TransferByteSPI(letter);
spi_master_Rx_sync(&retvalues[2]);
PORTB |= (1<<PB0);
}while(retvalues[2] == 0xff);
}
int avr_init(void)
{
UART_Init(0,9600,8,UART_NoParity,1);
InitSPI_Master();
return(FALSE);
}
unsigned char TransferByteSPI(unsigned char byte)
{
SPDR = byte;
while(!(SPSR & (1<<SPIF)));
return SPDR;
}
void spi_master_Rx_sync(unsigned char *retvalues)
{
retvalues[0] = 0x00;
while (retvalues[0] == 0x00)
{retvalues[0] = TransferByteSPI(0x00);}
retvalues[1] = TransferByteSPI(0x00);
}
void InitSPI_Master(void)
{
DDRB = 0x00;
DDRB |= (1<<PB0)|(1<<PB1) | (1<<PB2) | (0 <<PB3); // Set MOSI, SCK and SS
PORTB |= (1<<PB0);
SPCR = 0x00;
SPCR |= (1<<SPE) |(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)| (0<<SPR0); // Enable SPI, Master, f/4
SPSR;
SPDR;
}

View file

@ -1,50 +0,0 @@
#ifndef MAIN_H
#define MAIN_H
#ifndef F_CPU
#define F_CPU 11059200
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef setBit
#define setBit(PORT, BITNUM) ((PORT) |= (1<<(BITNUM)))
#define clearBit(PORT, BITNUM) ((PORT) &= ~(1<<(BITNUM)))
#define toggleBit(PORT, BITNUM) ((PORT) ^= (1<<(BITNUM)))
#define nop() asm volatile ("nop")
#endif
#define ICOM_MSG_LENGTH 0x18
#define ICOM_DELAY 500
#define RS 4
#define RW 5
#define ENABLE 6
int avr_init(void);
void InitSPI_Master(void);
void LCDSPI_WriteString(char *str);
unsigned char LCDSPI_MoveCursor(unsigned char addr, unsigned char *retvalues);
unsigned char LCDSPI_GetAddress(unsigned char *retvalues);
unsigned char LCDSPI_GetRamContent(unsigned char *retvalues);
void LCDSPI_SendCommand(unsigned char cmd, unsigned char *retvalues);
void LCDSPI_WriteLetter(unsigned char letter, unsigned char *retvalues);
int avr_init(void);
unsigned char TransferByteSPI(unsigned char byte);
void spi_master_Rx_sync(unsigned char *retvalues);
int define_symbol(uint8_t symbol_no, uint8_t line0, uint8_t line1, uint8_t line2, uint8_t line3,uint8_t line4, uint8_t line5, uint8_t line6, uint8_t line7);
#endif

View file

@ -1,434 +0,0 @@
# Hey Emacs, this is a -*- makefile -*-
#
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
# Released to the Public Domain
# Please read the make user manual!
#
# Additional material for this makefile was submitted by:
# Tim Henigan
# Peter Fleury
# Reiner Patommel
# Sander Pool
# Frederik Rouleau
# Markus Pfaff
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
#
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# 4.07 or greater).
#
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only
#
# To rebuild project do "make clean" then "make all".
#
# MCU name
MCU = atmega32
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = main
# clock frequency
F_CPU = 11059200
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
SRC += iodriver/avr/avr_uart.c
SRC += lcd_routines.c
#SRC += iodriver/mini_atmega_testboard.c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = 3
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS =
# Place -I options here
CINCS =
# Compiler flags.
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
#CFLAGS = -g$(DEBUG)
CFLAGS = $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
#CFLAGS += -S
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes -Wmissing-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
CFLAGS += -pedantic
# Assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
#Additional libraries.
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
SCANF_LIB =
MATH_LIB = -lm
# External memory options
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x808000,--defsym=__heap_end=0x80ffff
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x802000,--defsym=__heap_end=0x809fff
#EXTMEMOPTS = -Wl,-Tdata=0x802000,--defsym=__heap_end=0x809fff
EXTMEMOPTS =
# Linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
# Programming support using avrdude. Settings and variables.
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkii
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
# ---------------------------------------------------------------------------
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) -DF_CPU=$(F_CPU)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter finished end
build: elf hex eep lss sym s
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
s: $(TARGET).s
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
finished:
@echo $(MSG_ERRORS_NONE)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program:
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# STK500 -cUSB -d$(MCU) -e -if$(TARGET).hex -pf -vf -I2000000
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program

View file

@ -1,541 +0,0 @@
#include <avr/io.h>
#include <avr/signal.h>
#include "iodriver/avr/avr_uart.h"
/*****************************************************************************
Name: UART_Init
Description: intizialization of UART according to processortype
(__AVR_ATmega8__ | __AVR_ATmega16__ | __AVR_ATmega32__ |
__AVR_ATmega64__ | __AVR_ATmega163__ | __AVR_ATmega128__ |
__AVR_AT90CAN128__)
Parameters: unsigned char UARTNr UART0(0x00) or UART1(0x01)
unsigned long BaudrateValue i.e. 115200 or 9600
char databits 5 to 9
char parity 0 = no parity
1 = odd parity
2 = even parity
char stopbit 1 or 2
Returns: 0x00 no error, no warning
0x01 invalid UART-Number setting
0x02 invalid number of databits
0x04 invalid parity setting
0x08 invalid number of stopbits
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_Init(unsigned char UARTNr, unsigned long Baudrate, char databits, char parity, char stopbit)
{
int error = 0x00;
unsigned char csra_value=0;
unsigned char csrb_value=0;
unsigned char csrc_value=0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
// check off invalid parameters
if((databits < 5) || (databits > 9))
{
error = 0x02;
}
else if((parity+1 < UART_NoParity+1) || (parity+1 > UART_OddParity+1)) // +1 bypass "warning message" with equation "x < 0"
{
error = 0x04;
}
else if((stopbit < 1) || (stopbit > 2))
{
error = 0x08;
}
else // all parameters in a valid range
{
// setting of uart transmission speed (single)
csra_value &= ~(1 << U2X);
// baud rate register setting
if (databits < 9)
{
csrc_value |= ((databits-5) << 1);
}
else
{
csrc_value |= 0x06;
csrb_value |= 0x04;
}
// setting chosen parity-mode
csrc_value |= parity << 4;
// setting number of chosen stopbit(s)
csrc_value |= ((stopbit-1)<<3);
// enables receiver and transmitter
csrb_value |= ((1 << TXEN) | (1 << RXEN));
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UBRR0H = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRR0L = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSR0A = csra_value;
UCSR0B = csrb_value;
UCSR0C = csrc_value;
clearBit(DDRE,0); // UART RxD
setBit(DDRE,1); // UART TxD
setBit(PORTE,1); // UART TxD
}
else
{
UBRR1H = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRR1L = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSR1A = csra_value;
UCSR1B = csrb_value;
UCSR1C = csrc_value;
clearBit(DDRD,2); // UART RxD
setBit(DDRD,3); // UART TxD
setBit(PORTD,3); // UART TxD
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
UBRRH = (unsigned char)(UART_BAUD_CALC(Baudrate)>>8);
UBRRL = (unsigned char)UART_BAUD_CALC(Baudrate);
UCSRA = csra_value;
UCSRB = csrb_value;
UCSRC = 0x80 | csrc_value;
clearBit(DDRD,0); // UART RxD
setBit(DDRD,1); // UART TxD
setBit(PORTD,1); // UART TxD
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*****************************************************************************
Name: UART_WriteChar
Description: transmit char via UART
Parameters: unsigned char UARTNr UART0 or UART1
char AChar char to transmit
Returns: 0x00 no error, no warning
0x01 ERROR
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_WriteChar(unsigned char UARTNr, char AChar)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if(UARTNr > 1)
{
error = TRUE;
}
else
{
if(UARTNr==0)
{
while(bit_is_clear(UCSR0A,UDRE0));
UDR0=AChar;
}
else
{
while(bit_is_clear(UCSR1A,UDRE1)); //while(!(UCSR1A & (1<<UDRE1)));
UDR1=AChar;
}
}
#else
if(UARTNr != 0)
{
error = TRUE;
}
else
{
while(bit_is_clear(UCSRA,UDRE));
UDR=AChar;
}
#endif
return(error);
}
/*****************************************************************************
Name: UART_WriteString
Description: transmit string via UART
Parameters: unsigned char UARTNr UART0 or UART1
char * AString pointer to string
Returns: 0x00 no error
0x01 error in uartnumber
0x02 string is empty
0x03 error while UART_WriteChar
0x04 string to transmit is greater than length of integer
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_WriteString(unsigned char UARTNr, char *AString)
{
unsigned int n = 0;
unsigned char TxChar;
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if(UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
TxChar = AString[0];
if(TxChar==0)
{
error = 0x02;
}
else
{
do
{
if(UART_WriteChar(UARTNr,TxChar))
{
error = 0x03;
}
if(++n == 0)
{
error = 0x04;
}
TxChar = AString[n];
}
while((TxChar != 0) && (error == 0));
}
}
return(error);
}
/*****************************************************************************
Name: UART_ReceiveChar
Description: receive a char via UART
Attention: Functions waits in while-loop until a char received
Parameters: unsigned char UARTNr UART0 or UART1
char *rx_byte pointer to char
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_ReceiveChar(unsigned char UARTNr, char *rx_byte)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
else
{
if (UARTNr==0)
{
while(!(UCSR0A & (1<<RXC0)));
*rx_byte = UDR0;
}
else
{
while(!(UCSR1A & (1<<RXC1)));
*rx_byte = UDR1;
}
}
#else
if(UARTNr != 0)
{
error = 0x01;
}
else
{
while (!(UCSRA & (1<<RXC))); // wait till char is available
*rx_byte = UDR;
}
#endif
return(error);
}
/*****************************************************************************
Name: UART_EnableRxInt
Description: enable Rx Interrupt
Parameters: unsigned char UARTNr UART0 or UART1
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_EnableRxInt(unsigned char UARTNr)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UCSR0B |= (1 << RXCIE0);
}
else
{
UCSR1B |= (1 << RXCIE1);
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
if (UARTNr==UART0)
{
UCSRB |= (1 << RXCIE);
}
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*****************************************************************************
Name: UART_DisableRxInt
Description: enable Rx Interrupt
Parameters: unsigned char UARTNr UART0 or UART1
Returns: 0x00 no error
0x01 error in uartnumber
******************************************************************************
2006.07.03 BSH create File
******************************************************************************
Changes:
*****************************************************************************/
int UART_DisableRxInt(unsigned char UARTNr)
{
int error = 0;
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr > 1)
{
error = 0x01;
}
#else
if (UARTNr != 0)
{
error = 0x01;
}
#endif
if(!error)
{
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
if (UARTNr==UART0)
{
UCSR0B &= ~(1 << RXCIE0);
}
else
{
UCSR1B &= ~(1 << RXCIE1);
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
if (UARTNr==UART0)
{
UCSRB &= ~(1 << RXCIE);
}
#else
#error "NOT A VALID DEVICE FOR UART INITIALIZATION"
#endif
}
return(error);
}
/*
#if defined (__AVR_ATmega128__) || defined (__AVR_ATmega64__) || defined (__AVR_AT90CAN128__)
SIGNAL(SIG_UART0_RECV)
{
unsigned char c;
c = UDR0;
}
SIGNAL(SIG_UART1_RECV)
{
unsigned char c;
c = UDR1;
}
#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega163__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega32__)
SIGNAL(SIG_UART_RECV)
{
unsigned char c;
c = inp(UDR);
}
#endif
*/
/*****************************************************************************
Functionname: *UART_ReceiveString
Functiondescription: receive a string via UART with
this functions waits until a char received
function endswhen <CR> or <LF> received
Parameters: unsigned char UARTNr UART0 or UART1
char *s string to copy received string
unsigned char charmax number of max char to receive
Returns: char *s received string
******************************************************************************
03. 05. 2006 BSH
******************************************************************************
Changes:
******************************************************************************
char *UART_ReceiveString(unsigned char UARTNr, char *s, unsigned char charmax)
{
unsigned char c;
char *cs;
cs = s; // copy string in a new string
while(charmax > 1)
{
charmax--;
c = UART_ReceiveChar(UARTNr);
if(c == 0x08) // if Backspace
{
if(cs > s)
{
UART_WriteChar(UARTNr, ' ');
UART_WriteChar(UARTNr, 0x08);
cs--;
charmax++;
charmax++;
}
else
{
//UART_WriteChar(UARTNr, ' ');
// arrow key right
UART_WriteChar(UARTNr, 0x1B);
UART_WriteChar(UARTNr, 0x5B);
UART_WriteChar(UARTNr, 0x43);
charmax++;
}
}
else
{
if (( c == 0x0D ) || ( c == 0x0A )) // if "carriage Return" or "Line Feed"
//if ( c == 0x0D ) // if "carriage Return"
{
charmax = 0;
}
else
{
*cs = c;
cs++;
}
}
}
*cs = '\0'; // close a String with NULL
return(s);
}
*/
/*****************************************************************************
Functionname: UART_TransmitHex
Example UART_TransmitHex('B');
Output 0x42
******************************************************************************
03. 05. 2006 BSH
******************************************************************************
Changes:
******************************************************************************
int UART_TransmitHex(unsigned char UARTNr, char s)
{
unsigned char x = 0;
x = (s & 0xF0);
x = x >> 4;
if (UART_WriteChar(UARTNr, '0')) {return(TRUE);}
if (UART_WriteChar(UARTNr, 'x')) {return(TRUE);}
if(x < 10)
{
if (UART_WriteChar(UARTNr, (0x30 + x))) {return(TRUE);}
}
else
{
if (UART_WriteChar(UARTNr, (0x37 + x))) {return(TRUE);}
}
x = (s & 0x0F);
if(x < 10)
{
if (UART_WriteChar(UARTNr, (0x30 + x))) {return(TRUE);}
}
else
{
if (UART_WriteChar(UARTNr, (0x37 + x))) {return(TRUE);}
}
return(FALSE);
}
*/

View file

@ -1,37 +0,0 @@
#ifndef _AVR_UART_H_
#define _AVR_UART_H_
#ifndef F_CPU
#define F_CPU 11059200
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#ifndef setBit
#define setBit(PORT, BITNUM) ((PORT) |= (1<<(BITNUM)))
#define clearBit(PORT, BITNUM) ((PORT) &= ~(1<<(BITNUM)))
#define toggleBit(PORT, BITNUM) ((PORT) ^= (1<<(BITNUM)))
#define nop() __asm__ __volatile__ ("nop" ::)
#endif
#define UART0 0
#define UART1 1
#define UART_NoParity 1
#define UART_EvenParity 2
#define UART_OddParity 3
#define UART_BAUD_CALC(UART_BAUD_RATE) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
int UART_Init(unsigned char UARTNr, unsigned long Baudrate, char databits, char parity, char stopbit);
int UART_WriteChar(unsigned char UARTNr, char AChar);
int UART_WriteString(unsigned char UARTNr,char *AString);
int UART_ReceiveChar(unsigned char UARTNr, char *rx_byte);
int UART_EnableRxInt(unsigned char UARTNr);
int UART_DisableRxInt(unsigned char UARTNr);
#endif // _AVR_UART_H_

View file

@ -1,149 +0,0 @@
#include <avr/io.h>
#include <stdlib.h>
#include "spi_slave.h"
#define F_CPU 11059200
#include "lcd_routines.c"
#include "uart_atmega16.c"
#define BAUD 38400
#define VERSION 1
#define SERIALNO 1
static void printInt(unsigned char i)
{
int n = 0;
while(i>=100){
n++;
i-=100;
}
if(n){
LCD_WriteCharWait(n+'0');
}else{
LCD_WriteCharWait(' ');
}
n=0;
while(n>=10){
n++;
i-=10;
}
LCD_WriteCharWait(n+'0');
LCD_WriteCharWait(i+'0');
}
void hallo(void)
{
LCD_WriteString("Hello World");
LCD_SetDRAM(0x40);
LCD_WriteString("SN:");
printInt(SERIALNO);
LCD_WriteString(" VER:");
printInt(VERSION);
}
int main(void)
{
uart_init(F_CPU/(16*BAUD)-1);
print("Hello world\r\n");
DDRA = 0xff;
DDRC = 0xff;
DDRB = (1<<PB6) | (1<<LCD_E) | (1<<LCD_RS) | (1<<LCD_RW); // Set MISO
spi_slave_init();
unsigned char command[2] = {0x00, 0x00};
unsigned char send[2] = {0x00, 0x00};
LCD_Init();
hallo();
while(1)
{
spi_slave_Rx(command, 2);
#ifdef DEBUG
char msg[16];
print("Rx 0x");
print(utoa(command[1]+(command[0]<<8), msg, 16));
print("\r\n");
#endif
if((command[0] & 0x40)==0x40 && LCD_isBusy())
{
send[0] = 0x7E;
send[1] = 0xBB;
}
else
{
send[0] = command[0];
send[1] = 0xdd;
switch(command[0])
{
case 0x44: //write data to instruction register
LCD_WriteCommand(command[1]);
send[1] = command[1];
break;
case 0x45: //write data to data register
LCD_WriteChar(command[1]);
send[1] = command[1];
break;
case 0x20:
case 0x40:
LCD_Init();
case 0x46:
case 0x26: //read ram address and busy flag
send[1] = LCD_ReadCommand();
break;
case 0x47: //read data from ram
send[1] = LCD_ReadChar();
break;
case 0x43: //set cursor on display (0 - 31)
if (command[1] < 16)
LCD_SetDRAM(command[1]);
else
LCD_SetDRAM(0x40 + command[1] - 16);
send[1] = command[1];
break;
case 0x42: //write data to display
LCD_WriteChar(command[1]);
send[1] = command[1];
break;
case 0x21:
Background_Light(command[1]);
break;
case 0x10:
switch(command[1])
{
case 0x00:
send[1] = VERSION;
break;
case 0x01:
send[1] = SERIALNO;
break;
}
break;
default:
send[0] = 0x7E;
send[1] = command[0];
break;
}
}
#ifdef DEBUG
print("Tx 0x");
print(utoa(send[1]+(send[0]<<8), msg, 16));
print("\r\n");
#endif
spi_slave_Tx(send, 2);
}
return 0;
}

View file

@ -1,267 +0,0 @@
/*
* lcd_routines.c
*
* Created on: 03.08.2011
* Author: Martin
*/
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_routines.h"
static inline uint8_t Enable_Impuls()
{
_delay_us(1);
LCD_CMD_PORT |= (1<<LCD_E);
_delay_us(LCD_E_WIDTH);
uint8_t ret_value = LCD_DATA_PIN;
LCD_CMD_PORT &= ~(1<<LCD_E);
return ret_value;
}
static inline void input()
{
LCD_DATA_PORT = 0x00;
LCD_DATA_PORT_DDR = 0x00;
}
static inline void out(uint8_t cmd)
{
LCD_DATA_PORT = cmd;
LCD_DATA_PORT_DDR = 0xff;
}
static inline void idle()
{
LCD_DATA_PORT=0xff; // Pull up on
LCD_DATA_PORT_DDR = 0x00; // Pins on Input
}
static inline void Read_Enable()
{
input();
LCD_CMD_PORT |= 1<<LCD_RW;
}
static inline void Read_Disable()
{
LCD_CMD_PORT &= ~(1<<LCD_RW);
idle();
}
void LCD_WriteCommand(uint8_t cmd)
{
out(cmd);
Enable_Impuls();
idle();
}
uint8_t LCD_ReadCommand(void)
{
uint8_t ret_value;
Read_Enable();
ret_value = Enable_Impuls();
Read_Disable();
return ret_value;
}
uint8_t LCD_ReadChar(void)
{
uint8_t ret_value = 0;
LCD_CMD_PORT |= 1<<LCD_RS;
Read_Enable();
ret_value = Enable_Impuls();
Read_Disable();
LCD_CMD_PORT &= ~(1<<LCD_RS);
idle();
return ret_value;
}
uint8_t LCD_isBusy(void)
{
return LCD_ReadCommand() & 0x80;
}
uint8_t LCD_Command(uint8_t cmd)
{
int16_t timeout = 2000;
while (LCD_isBusy()) {
if (--timeout <=0)
return 1;
_delay_us(1);
}
LCD_WriteCommand(cmd);
return 0;
}
void LCD_WriteChar(char val)
{
LCD_CMD_PORT |= (1<<LCD_RS);
out(val);
Enable_Impuls();
LCD_CMD_PORT &= ~(1<<LCD_RS);
idle();
}
int LCD_WriteCharWait(char val)
{
int16_t timeout = 2000;
while (LCD_isBusy()) {
if (--timeout <=0)
return 1;
_delay_us(1);
}
LCD_WriteChar(val);
return 0;
}
void LCD_WriteString(char *string)
{
while(*string){
LCD_WriteCharWait(*string);
string++;
}
}
void LCD_Init(void)
{
_delay_ms(40);
LCD_CMD_PORT = 0x00;
LCD_WriteCommand(0x39); //function set 0011 1001 "instruction table 1"
_delay_ms(5);
LCD_WriteCommand(0x39);
_delay_ms(1);
LCD_WriteCommand(0x39);
_delay_ms(5);
LCD_WriteCommand(0x14); //bias set 0001 0100
_delay_ms(2);
LCD_WriteCommand(0x55); //power control 0101 0101
_delay_ms(2);
LCD_WriteCommand(0x6d); //follower ctrl 0110 1101
_delay_ms(2);
LCD_WriteCommand(0x78); //contrast set 0111 1000
_delay_ms(2);
LCD_WriteCommand(0x0c); //display 0000 1100
_delay_ms(1);
LCD_ClearDisplay();
_delay_ms(1);
LCD_WriteCommand(0x06); //auto increment 0000 0110
LCD_WriteCommand(0x38); // instruction table 0
_delay_ms(1);
Background_Light(1);
_delay_ms(1);
}
void LCD_SetDRAM(int addr)
{
LCD_Command((1 << 7) + addr);
}
void LCD_SetCGRAM(int addr)
{
LCD_WriteCommand((1 << 6) + addr);
}
void LCD_ClearDisplay(void)
{
LCD_WriteCommand(0x01);
}
void Background_Light(int on)
{
DDRD |= (1<<5);
if (on&1)
PORTD |= (1<<5);
else
PORTD &=~(1<<5);
return;
}
void LCD_SetCharacter(int adresse,int spalte,int on)
{
uint8_t data = 0;
uint8_t old_line = 0;
spalte = 4-spalte;
LCD_SetCGRAM(adresse);
old_line = LCD_ReadChar();
if(on==1)
{
data=(old_line)|(1<<spalte);
}
else
{
data = (old_line)&(~(1<<spalte));
}
LCD_SetCGRAM(adresse);
LCD_WriteChar(data);
return;
}
void Set_Pix(int x,int y,int on)
{
if ((x<0)|(x>19)|(y<0)|(y>15))
return;
uint8_t DDRAM_adresse = x;
DDRAM_adresse += 0x0c;
int i=0;
for(i=0;x<5;i++)
{
x -=5;
}
DDRAM_adresse += i;
if(y>7)
{
DDRAM_adresse += 0x40;
y -= 8;
}
uint8_t CGRAM_adresse;
switch(DDRAM_adresse){
case 0x0c: CGRAM_adresse=0x00; //cgramCode für display stelle reservieren
break;
case 0x0d: CGRAM_adresse=0x08;
break;
case 0x0e: CGRAM_adresse=0x10;
break;
case 0x0f: CGRAM_adresse=0x18;
break;
case 0x4c: CGRAM_adresse=0x20;
break;
case 0x4d: CGRAM_adresse=0x28;
break;
case 0x4e: CGRAM_adresse=0x30;
break;
case 0x4f: CGRAM_adresse=0x38;
break;
}
uint8_t Character_Code = CGRAM_adresse;
CGRAM_adresse += y;
LCD_SetCharacter(CGRAM_adresse,x,on);
LCD_SetDRAM(DDRAM_adresse);
LCD_WriteChar(Character_Code);
return;
}

View file

@ -1,33 +0,0 @@
/*
* lcd_routines.h
*
* Created on: 03.08.2011
* Author: Martin
*/
#ifndef LCD_ROUTINES_H_
#define LCD_ROUTINES_H_
#define LCD_DATA_PORT PORTA
#define LCD_DATA_PIN PINA
#define LCD_DATA_PORT_DDR DDRA
#define LCD_CMD_PORT PORTB
#define LCD_RS 2
#define LCD_E 0
#define LCD_RW 1
#define LCD_E_WIDTH 10
void LCD_WriteCommand(uint8_t cmd);
uint8_t LCD_ReadCommand(void);
uint8_t LCD_ReadChar(void);
uint8_t LCD_isBusy(void);
void LCD_WriteChar(char val);
void LCD_Init(void);
void LCD_SetDRAM(int addr);
void LCD_ClearDisplay(void);
void LCD_SetCGRAM(int adresse);
void LCD_SetCharacter(int adresse,int spalte,int on);
void Set_Pix(int x,int y, int set);
void Background_Light(int on);
#endif /* LCD_ROUTINES_H_ */

View file

@ -1,27 +0,0 @@
#include <avr/io.h>
#define UDRE 5
#define TXEN 3
#define URSEL 7
#define UCSZ0 1
#define UCSZ1 2
void uart_init(unsigned short ubrr)
{
UBRRH = (ubrr>>8); // hier ginge auch UBRRH=0;
UBRRL = ubrr;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8 bit modus
UCSRB = (1<<TXEN); // enable Transmitter
}
void uart_transmit(unsigned char a)
{
while (!(UCSRA & (1<<UDRE))) // warte bis UDR bereit ist
{}
UDR=a;
}
void print(char *s)
{
while (*s)
uart_transmit(*s++);
}

View file

@ -1,91 +0,0 @@
CPU_StepperControl = atmega16m1
CPU_ECRIS_REMOTE=atxmega128a1
CPU_lcd=atmega16
CPU_sologse=atmega644
CPU_chaos=atmega32m1
pMCU-atmega16m1 = m16
pMCU-atmega32m1 = m32m1
pMCU-atmega16 = m16
pMCU-atmega644 = m644
MCU = $(CPU_$*)
CC=avr-gcc -Wall -MMD -std=c99 -O3 -mmcu=$(MCU) \
-funsigned-char \
-funsigned-bitfields \
-fpack-struct \
-fshort-enums \
-fverbose-asm
CFLAGS = $($*_CFLAGS) $(DEBUG)
%.s: %.c
$(CC) -S $(CFLAGS) $<
%.o: %.c
$(CC) -gstabs -c $(CFLAGS) $<
-include *.d
LDFLAGS =
%.elf: %.o
$(CC) $(CFLAGS) -Wl,-Map=$*.map,--cref $^ --output $@ $(LDFLAGS)
OBJCOPY = avr-objcopy
%.hex: %.elf
$(OBJCOPY) -O ihex -R .eeprom $< $@
%.eeprom: %.elf
$(OBJCOPY) -O ihex -j .eeprom --change-section-lma .eeprom=0 $< $@
AVRDUDE = avrdude
AVRDUDE_PROGRAMMER = avrispmkii
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$<
AD = $(AVRDUDE) -p $(pMCU-$(MCU)) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
%.burn: %.hex
$(AD) -U flash:v:$< || $(AD) -U flash:w:$<
lfuse_lcd=0xff
# CKDIV8 : no
# CKOUT: yes, on PB1, pin 41
# SUT: max
# CLKSEL: external clock
lfuse_sologse=0xA0
lfuse_chaos=0xef
chaos_CFLAGS = -I.
chaos.o: ads8688.h ltc1655.h spi_slave.h tick.h hvosc.h hvled.h
chaos.s: ads8688.h ltc1655.h spi_slave.h tick.h hvosc.h hvled.h
chaos.hex: chaos.eeprom
%.lfuse:
$(AD) -B 5 -U lfuse:w:$(lfuse_$*):m
%.id:
$(AD) -B 5 -U lfuse:v:$(lfuse_$*):m
clean:
rm -f *.hex *.o *.s *.map *.elf *.d
VPATH = .:LCD/lcd_slave_sync:sologse:chaos
lcd_CFLAGS = -I. -DDEBUG
lcd.o: lcd.c spi_slave.h lcd_routines.h lcd_routines.c uart_atmega16.c
.PHONY: eeprom.eeprom
%.eeprom.eeprom: %.hex
$(AD) -U eeprom:r:$@
%.eeprom.burn: %.eeprom
$(AD) -U eeprom:v:$< || $(AD) -U eeprom:w:$<
%.ad:
$(AD) -v -t

View file

@ -1,327 +0,0 @@
/*
* StepperControl.c
*
* Created: 23.09.2011 13:13:14
* Author: Lauri
*
* PinAssignements:
* 0 1 2 3 4 5 6 7
* PB: MISO MOSI step MS2 MS1 - enable SCK
* PC: - - - - sleep reset MS3 DAC
* PD: - - trigger SSel - - - direction
*
*/
#include <avr/io.h>
#define PORTB_mode 0b01011000
#define PORTB_MS1 0b00010000
#define PORTB_MS2 0b00001000
#define PORTB_STEP 0b00000100
#define PORTB_ENABLE 0b01000000
#define PORTC_mode 0b01110000
#define PORTC_MS3 0b01000000
#define PORTC_RESET 0b00100000
#define PORTC_SLEEP 0b00010000
#define PORTD_TRIG 0b00000100
#define PORTD_DIR 0b10000000
#define PORTB_MISO (1<<DDB0)
#include "spi_slave.h"
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
// Definition of the outputs
static void set_IO_Port_dir ()
{
DDRB = PORTB_mode | PORTB_ENABLE | PORTB_STEP | PORTB_MISO;
DDRC = PORTC_mode | (1 << DDC7); // DAC
DDRD = PORTD_TRIG | PORTD_DIR;
spi_slave_init();
}
// the DAC controls the stepper current
static void set_dac(uint8_t dac_value_h)
{
// use Vref as reference voltage (see pp. 245-7)
ADMUX = 0;
ADCSRB = (1<<AREFEN);
DACON = (1<<DALA); // defines usage of the DACL/H registers
// write DACL before DACH
DACL = 0;
DACH = dac_value_h;
DACON |= (1<<DAEN) | (1<<DAOE); // enables the DAC and its output
}
static uint8_t get_dac()
{
return DACH;
}
// Timer 1 defines step frequency
static void set_prescale(uint8_t prescale)
{
uint8_t wgm = 0b1100; // CTC by ICR1
TCCR1A = wgm & 0b0011; // no output
TCCR1B = ((wgm & 0b1100) << 1) | prescale & 7;
}
inline static uint8_t get_prescale()
{
return TCCR1B & 7;
}
static inline void set_step_freq(uint16_t v)
{
ICR1 = v;
}
static inline uint16_t get_step_freq()
{
return ICR1;
}
static inline void wait_for_step_tick()
{
while (!(TIFR1 & (1<<ICF1))) ;
TIFR1 = (1<<ICF1); // reset the ICF1 bit
}
// stepper chip controls
#define MODE_MS 0b00000111
#define MODE_ENABLE PORTB_ENABLE
#define MODE_RESET PORTC_RESET
#define MODE_SLEEP PORTC_SLEEP
static void set_mode(uint8_t mode)
{
uint8_t portb = PORTB & ~PORTB_mode;
portb |= mode & MODE_ENABLE | ((mode&3)<<3);
PORTB = portb;
uint8_t portc = PORTC & ~PORTC_mode;
portc |= mode & (MODE_RESET|MODE_SLEEP) | ((mode&4)<<4);
PORTC = portc;
}
static uint8_t get_mode()
{
uint8_t portb = PORTB;
uint8_t portc = PORTC;
return portb & MODE_ENABLE
| portc & (MODE_RESET|MODE_SLEEP)
| (portb>>3)&3 | (portc>>4)&4;
}
static inline void set_direction(uint8_t dir)
{
if (dir)
PORTD |= PORTD_DIR;
else
PORTD &=~ PORTD_DIR;
}
static inline void set_enable(uint8_t en)
{
if (en)
PORTB |= PORTB_ENABLE;
else
PORTB &=~ (PORTB_ENABLE | PORTB_STEP);
}
// This is the main sequencer
// ntriggers: number of cycles
// ntics: number of timer tics per cycles / 2
// nsteps: number of stepper motor steps
// tpos: step number where the trigger shall be sent.
static uint8_t run(uint16_t ntriggers,
uint16_t ntics,
uint16_t nsteps,
uint16_t tpos)
{
wait_for_step_tick();
for (uint16_t i = 0; i<ntriggers; i++) {
for (uint16_t j=0; j<ntics; j++) {
wait_for_step_tick();
if (j<nsteps)
PORTB |= PORTB_STEP;
if (likely(j==tpos))
PORTD |= PORTD_TRIG;
wait_for_step_tick();
PORTB &=~ PORTB_STEP;
PORTD &=~ PORTD_TRIG;
if (unlikely(spi_slave_Rx_status())) {
return 1;
}
}
}
return 0;
}
#define FLAG_DIR 0b00000001
#define FLAG_TRIG 0b00000010
#define FLAG_PAUSE 0b00000100
#define FLAG_GO 0b00001000
#define FLAG_RDIR 0b00010000
#define FLAG_RTRIG 0b00100000
#define FLAG_RPAUSE 0b01000000
#define FLAG_RET 0b10000000
// scan parameters:
static uint16_t triggers, tics, steps, trigger_position;
static inline uint8_t scan(uint8_t flags)
{
for ( ; flags; flags>>=4)
if (flags & FLAG_GO) {
set_direction(flags&FLAG_DIR);
uint16_t tpos = flags&FLAG_TRIG ? trigger_position : tics;
uint16_t tcs = flags&FLAG_PAUSE ? tics : steps;
if (run(triggers, tcs, steps, tpos))
return 1;
}
return 0;
}
static inline uint8_t move(uint8_t dir, uint8_t steps)
{
set_direction(dir);
return run(1, steps, steps, steps);
}
static inline uint8_t trigger()
{
return run(1, 1, 0, 0);
}
static void set_defaults()
{ // initial frequency is 11.059.200Hz
set_prescale(2); // options: 1-8-64-256-1024 set by 1-2-3-4-5
set_mode(MODE_MS | MODE_ENABLE);
set_dac(64); // equals 0.75A ([dac_value/8bit] * [3.3V/2Ohm])
set_step_freq(431); // leads to a stepping frequency of 100Hz
// step rate = 11059200 / 8 / (431+1) / 2 / 16
}
int main(void)
{
// initializing
set_IO_Port_dir();
set_defaults();
const uint8_t magic = 0xe4;
while (1) {
uint8_t cmd[3];
spi_slave_Rx(cmd, 3);
uint16_t val = cmd[1] | (cmd[2]<<8);
uint16_t res = 0;
switch (cmd[0]) {
// execute the sequencer
// require a magic token at the end of the command
case 0x40:
case 0x41:
if (cmd[2] == magic)
res = (~magic<<8) | move(cmd[0]&1, cmd[1]);
break;
case 0x42:
if (cmd[2] == magic)
res = (~magic<<8) | trigger();
break;
case 0x43:
if (cmd[2] == magic)
res = (~magic<<8) | scan(cmd[1]);
break;
// stepper mode
case 0x50:
res = get_mode();
break;
case 0x51:
res = get_mode();
set_mode(res | val);
break;
case 0x52:
res = get_mode();
set_mode(res &~ val);
break;
case 0x53:
res = get_mode();
set_mode(val);
break;
// stepper current
case 0x56:
res = get_dac();
break;
case 0x57:
res = get_dac();
set_dac(val);
break;
// timer parameter
case 0x58:
res = get_prescale();
break;
case 0x59:
res = get_prescale();
set_prescale(val);
break;
case 0x5a:
res = get_step_freq();
break;
case 0x5b:
res = get_step_freq();
set_step_freq(val);
break;
// scan parameter
case 0x60:
res = triggers;
break;
case 0x61:
res = triggers;
triggers = val;
break;
case 0x62:
res = tics;
break;
case 0x63:
res = tics;
tics = val;
break;
case 0x64:
res = steps;
break;
case 0x65:
res = steps;
steps = val;
break;
case 0x66:
res = trigger_position;
break;
case 0x67:
res = trigger_position;
trigger_position = val;
break;
}
cmd[1] = res;
cmd[2] = res>>8;
spi_slave_Tx(cmd, 3);
}
return 0;
}

View file

@ -1,115 +0,0 @@
#include "avr/io.h"
#define ADC_SDI 7
#define ADC_SCK 5
#define ADC_CE 4
#define ADC_SDO 1
#define ADC_RST 0
#define ADC_PO PORTD
#define ADC_PI PIND
#define ADC_PO_IO _SFR_IO_ADDR(ADC_PO)
#define ADC_PI_IO _SFR_IO_ADDR(ADC_PI)
static inline void ads8688_init()
{
DDRD |= 0xb0;
}
static inline void ads8688_write(unsigned char c, unsigned char i)
{
__asm__("sbrs %[c], %[i]" "\n\t"
"cbi %[p], %[d]" "\n\t"
"sbrc %[c], %[i]" "\n\t"
"sbi %[p], %[d]" "\n\t"
"sbi %[p], %[ck]" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"cbi %[p], %[ck]" "\n"
:
:[p] "n" (ADC_PO_IO),
[d] "n" (ADC_SDI),
[ck] "n" (ADC_SCK),
[c] "r" (c),
[i] "n" (i) );
}
static inline void ads8688_read(unsigned char *r, unsigned char *rr, unsigned char i)
{
// qq is a dummy requested here to avoid load/store between bytes.
__asm__("sbi %[pk], %[ck]" "\n\t"
"sbic %[pd], %[d]" "\n\t"
"ori %[q], %[i]" "\n\t"
"sbis %[pd], %[d]" "\n\t"
"andi %[q], %[ii]" "\n\t"
"cbi %[pk], %[ck]" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n"
:[q] "+d" (*r), // ORI needs r16..r31
[qq] "+d" (*rr)
:[pk] "n" (ADC_PO_IO),
[pd] "n" (ADC_PI_IO),
[d] "n" (ADC_SDO),
[ck] "n" (ADC_SCK),
[i] "n" (1<<i),
[ii] "n" (0xff&~(1<<i))
);
}
static inline void ads8688_frame(const unsigned char *c, unsigned char *r)
{
ADC_PO &=~ (1<<ADC_SCK);
ADC_PO &=~ (1<<ADC_CE);
ads8688_write(c[1], 7);
ads8688_write(c[1], 6);
ads8688_write(c[1], 5);
ads8688_write(c[1], 4);
ads8688_write(c[1], 3);
ads8688_write(c[1], 2);
ads8688_write(c[1], 1);
ads8688_write(c[1], 0);
ads8688_write(c[0], 7);
ads8688_write(c[0], 6);
ads8688_write(c[0], 5);
ads8688_write(c[0], 4);
ads8688_write(c[0], 3);
ads8688_write(c[0], 2);
ads8688_write(c[0], 1);
ads8688_write(c[0], 0);
unsigned char r0 = 0;
unsigned char r1 = 0;
__asm__("nop" "\n\t"
"cbi %[p], %[d]" "\n"
:
:[p] "n" (ADC_PO_IO),
[d] "n" (ADC_SDI)
);
ads8688_read(&r1, &r0, 7);
ads8688_read(&r1, &r0, 6);
ads8688_read(&r1, &r0, 5);
ads8688_read(&r1, &r0, 4);
ads8688_read(&r1, &r0, 3);
ads8688_read(&r1, &r0, 2);
ads8688_read(&r1, &r0, 1);
ads8688_read(&r1, &r0, 0);
ads8688_read(&r0, &r1, 7);
ads8688_read(&r0, &r1, 6);
ads8688_read(&r0, &r1, 5);
ads8688_read(&r0, &r1, 4);
ads8688_read(&r0, &r1, 3);
ads8688_read(&r0, &r1, 2);
ads8688_read(&r0, &r1, 1);
ads8688_read(&r0, &r1, 0);
ADC_PO &=~ (1<<ADC_SCK);
ADC_PO |= (1<<ADC_CE);
r[0] = r0;
r[1] = r1;
}

View file

@ -1,851 +0,0 @@
// irena spi slave to drive HV slow control ADC and DAC
// ATmega32M1
#define upcase(c) (!((c)&0x20))
const char *revision =
"$Id$";
#include "spi_slave.h"
#include "ads8688.h"
#include "ltc1655.h"
unsigned char read_adc(unsigned char c, unsigned char n);
void adc_read(unsigned char chs, unsigned char n);
unsigned int read_auxadc();
void dac_ramp(unsigned int target);
void ads8688_cmd(const unsigned char *c, unsigned char *r);
void ltc1655_cmd(const unsigned char *c);
void ads8688_config();
#include "hvled.h"
#include "tick.h"
#include "hvosc.h"
#include <avr/interrupt.h>
#include <avr/sleep.h>
void die()
{
while (1) {
cli();
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
sleep_cpu();
}
}
static inline unsigned char disable_irq()
{
unsigned char sreg = SREG;
cli();
return sreg;
}
static inline void enable_irq(unsigned char sreg)
{
if (sreg & (1<<SREG_I))
sei();
}
void avradc_enable(unsigned char c);
static inline unsigned int avradc_data()
{
unsigned int r = ADCL;
r |= ADCH << 8;
r |= ADMUX << 11;
return r;
}
static inline void avrdac_set(unsigned int d)
{
if (d)
DACON = 1<<DALA | 1<<DAEN | 1<<DAOE;
else {
DACON = 0;
return;
}
DACL = d;
DACH = d>>8;
}
#include <avr/wdt.h>
void wdt_init(unsigned char mode);
unsigned char wdt_count;
volatile unsigned char wdt_tick;
enum {
WDT_MODE_LIVE = 2, // = any command kick
WDT_MODE_KICK = 3, // only 'W' command kicks
WDT_MODE_HV = 4, // ≥ 'H' command kicks
WDT_MODE_ADC = 5, // ≥ 'T' command kicks
};
static inline void wdt_kick()
{
wdt_reset();
wdt_count = 0;
}
// ADS8688 gains Channels:
// 0: ±2.5 Vref = ± 10.24V 0: b: Iprim, 0.5V/A, ± 0.64V
// 1: ±1.25 Vref = ± 5.12V 1: 5: Vdrv, 0…10V
// 2: ±0.625 Vref = ± 2.56V 2: 1: HV Mon, ±5V
// 3: ±0.3125 Vref = ± 1.28V 3: 6: NTC, 0…5V
// b: ±0.15625 Vref = ± 0.64V 4: 6: Vprim/11, 0…5V
// 5: 0…2.5 Vref = 0…10.24V 5: 6: 5V/2, 0…5V
// 6: 0.1,25 Vref = 0… 5.12V 6: 1: I_bias, ±5V
// 7: 0.625 Vref = 0… 2.56V 7: 5: Idrv, 0…10V
// f: 0.3125 Vref = 0… 1.28V A: dac
#ifndef ADC_GAIN
# define ADC_GAINS 0x5166615bUL
#endif
#define MAGIC 0xc05c
#define VERSION 4
struct conf {
unsigned int magic; // 0
unsigned char version; // 2
unsigned char flags; // 3
unsigned char flags2; // 4
unsigned int dac; // 5
unsigned int dac_nominal; // 7
unsigned int dac_off; // 9
unsigned int tick_period; // 11
unsigned char wdt_timeout; // 13
unsigned char wdt_mode; // 14
unsigned char wdt_toggle; // 15
unsigned char avradc; // 16
unsigned int avrdac; // 17
unsigned int adcconf; // 19
unsigned long adcgain; // 21
unsigned char auxadc_n; // 25
unsigned char hvadc_ch; // 26
unsigned char hvadc_n; // 27
unsigned char safe; // 28
unsigned int hvadc_safe; // 29
unsigned char ddrc; // 31
unsigned char portc; // 32
unsigned char portc_on; // 33
unsigned char portc_off; // 34
unsigned char hvosc_freq; // 35
unsigned char hvosc_dc; // 36
unsigned char inpdis; // 37
unsigned char wdt_load; // 38
unsigned char padding; // 39
} conf; // 40
enum {
FLAG_WDT = 1,
FLAG_RAMP = 2,
FLAG_ADC = 4,
FLAG_DAC = 8,
FLAG_ADCCONF = 16,
FLAG_DACADC = 32,
FLAG2_PORTC = 1,
FLAG2_PC_HV = 2,
FLAG2_HVOSC = 4,
FLAG2_HVLED = 8,
FLAG2_INPDIS = 16,
};
__attribute__((section(".eeprom")))
const struct conf runconf[] = {
[0] = { // Default
.magic = MAGIC,
.version = VERSION,
.flags = FLAG_ADCCONF | FLAG_DACADC,
.flags2 = FLAG2_HVOSC | FLAG2_HVLED | FLAG2_INPDIS,
.wdt_mode = 1,
.wdt_timeout = 120, // 2 min
.wdt_toggle = 8, // sec
.tick_period = TICK_NS(1000000L), // 1ms ramp
.avradc = 0x7f, // off
.adcconf = 0x8500,// RST
.ddrc = 2, // OC1B HVOSC
.adcgain = ADC_GAINS,
.auxadc_n = 4,
.hvadc_ch = 2,
.hvadc_n = 2,
.hvadc_safe = 0,
.inpdis = 0x3f,
.wdt_load = 20,
},
[1] = { // ON
.magic = MAGIC,
.version = VERSION,
.flags = FLAG_WDT | FLAG_ADCCONF | FLAG_DACADC,
.flags2 = FLAG2_HVOSC | FLAG2_HVLED | FLAG2_INPDIS,
.wdt_mode = 4,
.wdt_timeout = 120, // 2 min
.wdt_toggle = 8, // sec
.tick_period = TICK_NS(1000000L), // 1ms ramp
.avradc = 0x7f, // off
.adcconf = 0x8500,// RST
.adcgain = ADC_GAINS,
.auxadc_n = 4,
.hvadc_ch = 2,
.hvadc_n = 2,
.hvadc_safe = 0,
.ddrc = 2, // OC1B HVOSC
.hvosc_freq = 60,
.hvosc_dc = 18,
.dac_off = 1000,
.dac_nominal = 46411, // 800 V
.inpdis = 0x3f,
},
[2] = { // SAFE
.magic = MAGIC,
.version = VERSION,
.safe = 1,
.flags = FLAG_WDT | FLAG_RAMP | FLAG_ADCCONF,
.flags2 = FLAG2_HVOSC | FLAG2_HVLED | FLAG2_INPDIS,
.wdt_timeout = 120, // 2 min
.wdt_toggle = 8, // sec
.tick_period = TICK_NS(1000000L), // 1ms ramp
.avradc = 0x7f, // off
.adcconf = 0x8500,// RST
.adcgain = ADC_GAINS,
.auxadc_n = 4,
.hvadc_ch = 2,
.hvadc_n = 2,
.hvadc_safe = 683 + 0x8000, // 30V
.ddrc = 2, // OC1B HVOSC
.inpdis = 0x3f,
},
};
void conf_init()
{
tick_init(conf.tick_period);
if (conf.flags & FLAG_WDT)
wdt_init(conf.wdt_mode);
if (conf.flags2 & FLAG2_HVOSC) {
conf.ddrc |= 2;
hvosc_init(conf.hvosc_freq, conf.hvosc_dc);
}
if (conf.flags & FLAG_ADCCONF)
ads8688_config();
if (conf.flags & FLAG_DACADC)
conf.dac = read_auxadc(conf.auxadc_n);
if (conf.flags & FLAG_ADC)
avradc_enable(conf.avradc);
if (conf.flags & FLAG_DAC)
avrdac_set(conf.avrdac);
if (conf.flags2 & FLAG2_HVLED) {
led_init();
}
if (conf.flags2 & FLAG2_PORTC) {
PORTC = conf.portc;
DDRC = conf.ddrc;
}
if (conf.flags2 & FLAG2_INPDIS) {
DIDR0 = conf.inpdis << 5;
DIDR1 = conf.inpdis >> 3;
}
if (conf.flags & FLAG_RAMP)
dac_ramp(conf.dac_nominal);
}
#include <avr/eeprom.h>
static inline
void eeprom_save(unsigned char a)
{
eeprom_write_block(&conf, (void*)(a*4), sizeof(conf));
}
static inline
void eeprom_load(unsigned char a)
{
eeprom_read_block(&conf, (void*)(a*4), sizeof(conf));
}
unsigned long adc_sum[9];
unsigned int adc_noise[9];
unsigned char adc_n[9];
unsigned char adc_status;
unsigned char adc_error;
unsigned int adc_aux;
unsigned int adc_hv;
int hv_is_safe()
{
return !hvosc_is_on()
&& conf.dac <= conf.dac_off
&& (!conf.hvadc_safe
|| adc_hv <= conf.hvadc_safe)
;
}
void toggle_hv_led()
{
if (conf.flags2 & FLAG2_HVLED) {
if (hv_is_safe())
led_toggle(LED_GREEN);
else
led_toggle(LED_RED);
}
}
void hv_led_on()
{
if (conf.flags2 & FLAG2_HVLED) {
if (hv_is_safe())
led_on(LED_GREEN);
else
led_on(LED_RED);
}
}
char spi_was_busy;
static inline
void spi_busy_init()
{
PCMSK2 |= 8; // PIND3 PCINT19
while (!(PIND & 8));
PCIFR = 4;
}
static inline
unsigned char spi_busy()
{
// Return true if the SSEL pin became low
unsigned char f = PCIFR & 4;
PCIFR = 4;
spi_was_busy = f && !(PIND & 8);
return spi_was_busy;
}
static inline
void clear_spi_busy()
{
const unsigned char *busy_msg = (const unsigned char *) "\xff\xff\xff" "EEY";
if (spi_was_busy && !(PIND & 8))
spi_slave_Tx(busy_msg, 6);
spi_was_busy = 0;
}
__attribute__((noinline))
void hv_safe()
{
conf.safe = 1;
hvosc_init(0, 0);
if (conf.flags2 & FLAG2_PC_HV)
PORTC = conf.portc_off;
unsigned char sreg = disable_irq();
ltc1655_cmd(INT2FRAME(conf.dac_off));
conf.dac = conf.dac_off;
unsigned int adc_last = 0xffff;
unsigned int toggle = 0;
if (conf.hvadc_safe) {
spi_busy_init();
while (!read_adc(conf.hvadc_ch, conf.hvadc_n)) {
if (spi_busy())
break;
wdt_reset();
if (adc_hv < conf.hvadc_safe || adc_hv >= adc_last)
break;
adc_last = adc_hv;
toggle++;
if (!toggle)
toggle_hv_led();
}
}
enable_irq(sreg);
hv_led_on();
}
unsigned char wdt_killed_us;
int main()
{
wdt_killed_us = MCUSR;
MCUSR = 0;
wdt_init(0);
// turn of unused IO modules
PRR = (1<<PRPSC)|(1<<PRCAN)|(1<<PRTIM1)|(1<<PRLIN)|(1<<PRADC);
spi_slave_init();
DDRB |= (1<<PB0); // make MISO an output
ads8688_init();
ltc1655_init();
eeprom_load(0);
if (conf.wdt_load
&& wdt_killed_us & (1<<WDRF)
&& conf.magic == MAGIC
&& conf.version == VERSION)
eeprom_load(conf.wdt_load);
if (conf.magic == MAGIC && conf.version == VERSION) {
conf_init();
if (conf.safe)
hv_safe();
}
while (1) {
sei();
clear_spi_busy();
unsigned char cmd[3];
unsigned char resp[3];
unsigned char c;
const char *p;
if (spi_slave_Rx_wdt(cmd, 3)) {
const unsigned char *wdt_msg =
(const unsigned char *) "\xff\xff\xff" "EEW";
spi_slave_Tx(wdt_msg, 6);
continue;
}
cli();
resp[0] = cmd[0];
if (conf.wdt_mode == WDT_MODE_LIVE)
wdt_kick();
switch (cmd[0]) {
default:
resp[0] = 'E';
resp[1] = 'E';
resp[2] = cmd[0];
break;
case 'D':
ltc1655_cmd(cmd+1);
int2frame(conf.dac, resp+1);
conf.dac = frame2int(cmd+1);
conf.safe = 0;
break;
case 'd':
int2frame(conf.dac_nominal, resp+1);
conf.dac_nominal = frame2int(cmd+1);
break;
case 'H':
int2frame(conf.dac, resp+1);
if (conf.wdt_mode >= WDT_MODE_HV)
wdt_kick();
sei();
spi_slave_Tx(resp, 3);
dac_ramp(frame2int(cmd+1));
continue;
case 'h':
if (conf.flags2 & FLAG2_PC_HV)
PORTC = conf.portc_on;
if (conf.flags2 & FLAG2_HVOSC)
hvosc_init(conf.hvosc_freq, conf.hvosc_dc);
int2frame(conf.dac, resp+1);
if (conf.wdt_mode >= WDT_MODE_HV)
wdt_kick();
sei();
spi_slave_Tx(resp, 3);
dac_ramp(conf.dac_nominal);
continue;
case 'Q':
case 'q':
resp[1] = conf.hvosc_freq;
resp[2] = conf.hvosc_dc;
if (upcase(cmd[0])) {
conf.hvosc_freq = cmd[1];
conf.hvosc_dc = cmd[2];
}
hvosc_init(conf.hvosc_freq, conf.hvosc_dc);
hv_led_on();
conf.safe = 0;
break;
case 'I':
case 'i':
int2frame(tick_freq(), resp+1);
if (upcase(cmd[0])) {
conf.tick_period = frame2int(cmd+1);
tick_init(conf.tick_period);
}
break;
case 'A':
ads8688_cmd(cmd+1, resp+1);
break;
case 'T':
case 't':
resp[1] = adc_status;
resp[2] = adc_error;
sei();
spi_slave_Tx(resp, 3);
if (cmd[1]) {
if (upcase(cmd[0])) {
if (conf.wdt_mode >= WDT_MODE_ADC)
wdt_kick();
adc_read(cmd[1], cmd[2]);
}
else
adc_aux = read_auxadc();
}
continue;
case 'R':
c = cmd[1];
if (c>8)
c = 8;
switch (cmd[2]) {
case 1: int2frame(adc_sum[c] >> 8, resp+1); break;
case 2: resp[1] = adc_sum[c]; resp[2] = adc_n[c]; break;
case 3: int2frame(adc_noise[c], resp+1); break;
default: resp[1] = adc_status; resp[2] = adc_error; break;
}
break;
case 'r':
if (cmd[1])
int2frame(adc_hv, resp+1);
else
int2frame(adc_aux, resp+1);
break;
case 'V':
p = revision;
c = cmd[1];
while (*p && c) {
p++;
c--;
}
resp[1] = *p;
resp[2] = cmd[1]-c;
break;
case 'w':
resp[1] = conf.wdt_mode;
resp[2] = wdt_count;
sei();
spi_slave_Tx(resp, 3);
hv_safe();
break;
case 'W':
if (cmd[1]==0xff && cmd[2]==0xd1)
die();
resp[1] = conf.wdt_mode;
resp[2] = conf.wdt_timeout;
if (cmd[2])
conf.wdt_timeout = cmd[2];
if (cmd[1])
wdt_init(cmd[1]);
else {
resp[2] = wdt_count;
wdt_kick();
toggle_hv_led();
}
break;
case 'm':
resp[2] = conf.flags2;
conf.flags2 &=~ cmd[2];
conf.flags2 |= cmd[1];
resp[1] = conf.flags2;
break;
case 'M':
resp[2] = conf.flags;
conf.flags &=~ cmd[2];
conf.flags |= cmd[1];
resp[1] = conf.flags;
break;
case 'S':
resp[1] = cmd[1];
resp[2] = sizeof(conf);
sei();
spi_slave_Tx(resp, 3);
eeprom_save(cmd[1]);
continue;
case 'L':
resp[1] = cmd[1];
resp[2] = sizeof(conf);
if ((cmd[1] | 0x20) == 'e')
eeprom_load(cmd[2]);
if (conf.magic != MAGIC || conf.version != VERSION) {
resp[0] = 'E';
resp[2] = conf.version;
if (cmd[1] != 'F')
break;
}
if (cmd[1] && upcase(cmd[1])) {
sei();
spi_slave_Tx(resp, 3);
conf_init();
continue;
}
break;
case 'B':
c = cmd[1] & 0x7f;
resp[2] = c;
if (c >= sizeof(conf)) {
resp[0] = 'E';
resp[1] = sizeof(conf);
break;
}
resp[1] = ((unsigned char *)(&conf))[c];
if (cmd[1] & 0x80)
((unsigned char *)(&conf))[c] = cmd[2];
break;
case 'C':
resp[1] = cmd[1];
resp[2] = PINC;
switch (cmd[1]) {
default:
resp[1] = 'E';
case 'R':
break;
case 'T':
PINC = cmd[2];
resp[2] = PINC;
break;
case 'W':
PORTC = conf.portc = cmd[2];
break;
case 'O':
case 'o':
resp[2] = DDRC;
if (upcase(cmd[1]))
DDRC = conf.ddrc = cmd[2];
break;
case 'A':
if (cmd[2]) {
resp[2] = conf.avradc;
conf.avradc = cmd[2];
avradc_enable(conf.avradc);
break;
}
int2frame(avradc_data(), resp+1);
break;
case 'D':
resp[2] = conf.avrdac;
conf.avrdac = cmd[2]<<8 | (conf.avrdac & 0xff);
avrdac_set(conf.avrdac);
break;
case 'd':
resp[2] = conf.avrdac;
conf.avrdac = cmd[2];
if (!cmd[2])
avrdac_set(0);
break;
}
break;
case 'Y': // peek
case 'y': // poke
resp[1] = cmd[1];
resp[2] = *(unsigned char *)(cmd[1]+0);
if (!upcase(cmd[0]))
*(unsigned char *)(cmd[1]+0) = cmd[2];
break;
case 'Z':
case 'z':
resp[1] = cmd[1];
switch (cmd[1]) {
case 0: resp[2] = wdt_killed_us; break;
}
if (upcase(cmd[0]))
break;
switch (cmd[1]) {
case 0: wdt_killed_us = cmd[2]; break;
}
break;
}
sei();
spi_slave_Tx(resp, 3);
}
}
__attribute__((noinline))
void ads8688_cmd(const unsigned char *c, unsigned char *r){ads8688_frame(c,r);}
__attribute__((noinline))
void ltc1655_cmd(const unsigned char *c){ltc1655_frame(c);}
void ads8688_config()
{
unsigned char r[2];
ads8688_cmd(INT2FRAME(conf.adcconf), r);
for (char i=0; i<8; i++)
ads8688_cmd((unsigned char []){
(conf.adcgain >> (4*i)) & 0xf,
2*i+11,
}, r);
}
volatile unsigned char adc_lock;
unsigned char read_adc(unsigned char c, unsigned char n)
{
unsigned char e = 0;
if (n>8)
n=8;
unsigned char nn = (1<<n) - 1;
unsigned char cc;
if (c >= 8) {
c = 8;
cc = 0;
}
else
cc = 1<<c;
unsigned char cmd[2] = {0, 0xc0 | (c << 2)};
unsigned char resp[2];
unsigned char i;
adc_lock = 1;
unsigned char sreg = disable_irq();
for (i=0; i<3; i++)
ads8688_cmd(cmd, resp);
enable_irq(sreg);
unsigned int s0 = frame2int(resp);
unsigned long s = s0;
int r = 0;
unsigned long q = 0;
spi_busy_init();
for (i=0; i<nn; i++) {
if (spi_busy()) {
e = adc_error |= cc;
goto out;
}
sreg = disable_irq();
ads8688_cmd(cmd, resp);
enable_irq(sreg);
unsigned int s1 = frame2int(resp);
s += s1;
int dd = s1 - s0;
if (dd > 127)
dd = 127;
if (dd < -127)
dd = -127;
signed char d = dd;
r += d;
q += d * d;
}
unsigned long rr = (long)r*r;
unsigned long qq = q << n;
unsigned long chi2 = qq - rr;
adc_sum[c] = s << (8-n);
chi2 >>= 2*n - 1;
chi2 += 1;
chi2 >>= 1;
adc_noise[c] = chi2;
adc_n[c] = n;
adc_status |= cc;
if (c == conf.hvadc_ch)
adc_hv = adc_sum[c] >> 8;
out:
adc_lock = 0;
return e;
}
void adc_read(unsigned char chs, unsigned char n)
{
adc_status = 0;
adc_error = 0;
unsigned char c;
for (c=0; c<8; c++) {
if (!((1<<c) & chs))
continue;
if (read_adc(c, n))
return;
}
}
unsigned int read_auxadc()
{
unsigned char n = conf.auxadc_n;
if (!read_adc(8, n))
adc_aux = adc_sum[8] >> 8;
return adc_aux;
}
void dac_ramp(unsigned int target)
{
conf.safe = 0;
unsigned char toggle = 0;
spi_busy_init();
while (conf.dac != target) {
if (spi_busy())
return;
if (!tick(TICKO))
continue;
wdt_kick();
unsigned char sreg = disable_irq();
if (target > conf.dac)
conf.dac += 1;
else
conf.dac = target;
ltc1655_cmd(INT2FRAME(conf.dac));
enable_irq(sreg);
toggle++;
if (!toggle)
toggle_hv_led();
}
hv_led_on();
}
ISR(WDT_vect)
{
wdt_reset();
wdt_count++;
if (wdt_count >= conf.wdt_toggle) {
if (conf.safe && conf.hvadc_safe && !adc_lock) {
adc_hv = 0;
read_adc(conf.hvadc_ch, conf.hvadc_n);
}
toggle_hv_led();
}
if (wdt_count < conf.wdt_timeout)
goto wdt_out;
wdt_count = 0;
hv_safe();
wdt_out:
__asm__("STS %[CSR], %[CE]" "\n\t"
"STS %[CSR], %[IE]" "\n"
::[CSR] "n" (&WDTCSR),
[CE] "r" ((unsigned char)(1<<WDCE | 1<<WDE | 1<<WDP2 | 1<<WDP1)),
[IE] "r" ((unsigned char)(1<<WDIE | 1<<WDE | 1<<WDP2 | 1<<WDP1))
);
wdt_tick = 1;
}
void wdt_init(unsigned char mode)
{
conf.wdt_mode = mode;
wdt_reset();
if (mode < WDT_MODE_LIVE) {
__asm__("STS %[CSR], %[CE]" "\n\t"
"STS %[CSR], %[IE]" "\n"
::[CSR] "n" (&WDTCSR),
[CE] "r" ((unsigned char)(1<<WDCE | 1<<WDIE | 1<<WDE | 1<<WDP2 | 1<<WDP1)),
[IE] "r" ((unsigned char)(1<<WDP2 | 1<<WDP1))
);
return;
}
// 1s timeout, WDT interrupt enabled
__asm__("STS %[CSR], %[CE]" "\n\t"
"STS %[CSR], %[IE]" "\n"
::[CSR] "n" (&WDTCSR),
[CE] "r" ((unsigned char)(1<<WDCE | 1<<WDE | 1<<WDP2 | 1<<WDP1)),
[IE] "r" ((unsigned char)(1<<WDIE | 1<<WDE | 1<<WDP2 | 1<<WDP1))
);
}
void avradc_enable(unsigned char c)
{
// c == 0…18: enable channel c
// c & 0x80: enable VREF and ADC power, needed for DAC
// c == 4: do not disable input, it is the SPI SCK
// cc >= 19: power VREF and ADC down
DIDR0 = 0;
DIDR1 = 0;
unsigned char cc = c&0x1f;
if (cc >= 19) {
if (c&0x80)
cc = 11;
else{
ADCSRB = 0;
ADCSRA = 1<<ADIF | 6<<ADPS0;
PRR |= (1<<PRADC);
return;
}
}
PRR &=~ (1<<PRADC);
// 2.56V reference
ADMUX = cc<<MUX0 | 3<<REFS0;
ADCSRB = 1<<AREFEN;
ADCSRA = ADATE<<1 | 1<<ADIF | 6<<ADPS0;
if (!(c&0x80))
ADCSRA |= 1<<ADEN;
ADCSRA |= 1<<ADSC;
}

View file

@ -1,33 +0,0 @@
#include "avr/io.h"
#define LED1 4
#define LED2 3
#define LED_PORT PORTB
#define LED_GREEN (1<<LED1)
#define LED_RED (1<<LED2)
#define LED_MASK (LED_GREEN | LED_RED)
static inline void led_init()
{
DDRB |= LED_MASK;
}
static uint8_t led_status()
{
return LED_PORT & LED_MASK;
}
static inline void led_off()
{
LED_PORT &=~ LED_MASK;
}
static inline void led_on(uint8_t color)
{
LED_PORT &= ~(LED_MASK & ~color);
LED_PORT |= color;
}
static inline void led_toggle(uint8_t color)
{
if (led_status() == color)
LED_PORT &=~ color;
else
led_on(color);
}

View file

@ -1,28 +0,0 @@
#include "avr/io.h"
static inline void hvosc_init(unsigned char freq, unsigned char dc)
{
PORTC &=~ (1<<PC1);
PORTD &=~ (1<<PD2);
DDRC |= (1<<PC1);
DDRD |= (1<<PD2);
if (!dc || freq <= dc) {
TCCR1A = 0;
return;
}
PRR &=~ (1<<PRTIM1);
TCCR1A = (2<<COM1A0) | (3<<COM1B0) | (2<<WGM10);
TCCR1B = (1<<CS10) | (2<<WGM12);
ICR1H = 0;
ICR1L = freq;
OCR1AH = 0;
OCR1AL = dc;
OCR1BH = 0;
OCR1BL = freq-dc;
}
static inline
int hvosc_is_on()
{
return TCCR1A;
}

View file

@ -1,63 +0,0 @@
#include "avr/io.h"
#define DAC_SDI 7
#define DAC_SCK 5
#define DAC_CE 6
#define DAC_PORT PORTD
#define DAC_PORT_IO _SFR_IO_ADDR(DAC_PORT)
static inline void ltc1655_init()
{
DDRD |= 0xe0;
}
static inline void ltc1655_bit(unsigned char c, unsigned char i)
{
__asm__("sbrs %[c], %[i]" "\n\t"
"cbi %[p], %[d]" "\n\t"
"sbrc %[c], %[i]" "\n\t"
"sbi %[p], %[d]" "\n\t"
"cbi %[p], %[k]" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"sbi %[p], %[k]" "\n"
::
[p] "n" (DAC_PORT_IO),
[d] "n" (DAC_SDI),
[k] "n" (DAC_SCK),
[c] "r" (c),
[i] "n" (i) );
}
static inline void ltc1655_frame(const unsigned char *c)
{
DAC_PORT &=~ (1<<DAC_SCK);
DAC_PORT &=~ (1<<DAC_CE);
ltc1655_bit(c[1],7);
ltc1655_bit(c[1],6);
ltc1655_bit(c[1],5);
ltc1655_bit(c[1],4);
ltc1655_bit(c[1],3);
ltc1655_bit(c[1],2);
ltc1655_bit(c[1],1);
ltc1655_bit(c[1],0);
ltc1655_bit(c[0],7);
ltc1655_bit(c[0],6);
ltc1655_bit(c[0],5);
ltc1655_bit(c[0],4);
ltc1655_bit(c[0],3);
ltc1655_bit(c[0],2);
ltc1655_bit(c[0],1);
ltc1655_bit(c[0],0);
__asm__(
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n\t"
"nop" "\n"
);
DAC_PORT &=~ (1<<DAC_SCK);
DAC_PORT |= (1<<DAC_CE);
}

View file

@ -1,75 +0,0 @@
#include "avr/io.h"
#ifdef TICKT1
// 16-bit Timer 1 PWM by OCR1A, prescaled by 256
#define TICK_RESOLUTION 23148L // ns
static inline void tick_init(const unsigned int c)
{
TCCR1A = (1<<WGM10)|(1<<WGM11);
TCCR1B = (1<<WGM12)|(1<<WGM13) | (1<<CS12);
OCR1AH = c >> 8;
OCR1AL = c;
}
static inline unsigned int tick_freq()
{
unsigned char r0 = OCR1AL;
unsigned char r1 = OCR1AH;
return r1<<8 | r0;
}
// Up to three independent clients can consume ticks.
// The TICKB user can setup its phase with OCR1B.
#define TICKO (1<<TOV1)
#define TICKA (1<<OCF1A)
#define TICKB (1<<OCF1B)
static inline unsigned char tick(const unsigned char flag)
{
unsigned char r = TIFR1 & flag;
if (r)
TIFR1 = flag;
return r;
}
#else // →~TICKT1
// 8-bit Timer 0 PWM by OCR0A, prescaled by 1024
#define TICK_RESOLUTION 93593L // ns
static inline void tick_init(const unsigned char c)
{
TCCR0A = (3<<WGM00);
TCCR0B = (1<<WGM02) | (5<<CS00);
OCR0A = c;
}
static inline unsigned char tick_freq()
{
return OCR0A;
}
// Up to three independent clients can consume ticks.
// The TICKB user can setup its phase with OCR0B.
#define TICKO (1<<TOV0)
#define TICKA (1<<OCF0A)
#define TICKB (1<<OCF0B)
static inline unsigned char tick(const unsigned char flag)
{
unsigned char r = TIFR0 & flag;
if (r)
TIFR0 |= flag;
return r;
}
#endif // !TICKT1
#define TICK_NS(ns) (((ns)+TICK_RESOLUTION/2)/TICK_RESOLUTION)

View file

@ -1,72 +0,0 @@
all: sologse.hex mtr3gse.hex
CPU_sologse=
CPU_mtr3gse=atmega644
MCU = atmega644
pMCU-atmega16m1 = m16
pMCU-atmega16 = m16
pMCU-atmega644 = m644
CC=avr-gcc -Wall -MMD -std=c99 -O3 -mmcu=$(MCU) \
-funsigned-char \
-funsigned-bitfields \
-fpack-struct \
-fshort-enums
SN=1
CFLAGS = $($*_CFLAGS) $(DEBUG) -I. -DSN="$(SN)"
C_FILES = adc.c hex.c io_base.c io_spi.c io_usart.c sologse.c timer.c
OBJS = $(patsubst %.c, %.o, $(C_FILES))
%.s: %.c
$(CC) $(CFLAGS) -S $<
%.o: %.c
$(CC) -gstabs $(CFLAGS) -c $<
-include *.d
LDFLAGS =
sologse.elf: solo.o
mtr3gse.elf: mtr3.o
%.elf: $(OBJS)
$(CC) $(CFLAGS) -Wl,-Map=$*.map,--cref $^ --output $@ $(LDFLAGS)
OBJCOPY = avr-objcopy
%.hex: %.elf
$(OBJCOPY) -O ihex -R .eeprom $< $@
AVRDUDE = avrdude
AVRDUDE_PROGRAMMER = avrispmkii
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$<
%.burn: %.hex
$(AVRDUDE) -p $(pMCU-$(MCU)) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
-U flash:w:$<
lfuse_LCD=0xff
# CKDIV8 : no
# CKOUT: yes, on PB1, pin 41
# SUT: max
# CLKSEL: external clock
lfuse_sologse=0xA0
lfuse_mtr3gse=0xA0
%.lfuse:
$(AVRDUDE) -p $(pMCU-$(MCU)) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
-B 5 -U lfuse:w:$(lfuse_$*):m
clean:
rm -f *.hex *.o *.s *.map *.elf *.d

View file

@ -1,53 +0,0 @@
All commands have to end with either of [\r, \n, 0x00]
'I' Print system infos.
[Options]
'I' Current state of all 4 ports (1x 32bit hex).
'P' Power. Voltage, current and temperature readings of the ADC (each as 16bit hex).
'T' Current onboard time. (1x 32bit hex).
'V' Version string. Info about the firmware version.
'M' Mode select. Change mode of different modules.
[Options]
'P' Power. Enable/disable logging of voltage/current.
[Options]
'0' Disable logging.
'1' Enable logging.
'U' USART BAUD. Change the speed at which the USART communicates.
[Options]
'0' Set speed to 38400bps.
'1' Set speed to 115400bps.
'T' Sync onboard clock. WARNING: This also resets the 1HZ clock.
'S' Change data order of the SPI.
[options]
'L' Lsb first.
'M' Msb first.
'F' Set/Get status of FPGA.
[Options]
'N' Set NCONFIG pin.
[Options]
'0' Set NCONFIG low.
'1' Set NCONFIG high.
'C' Set CONFDONE pin.
[Options]
'0' Set CONFDONE low.
'1' Set CONFDONE high.
'S' Print NSTATUS ('0' or '1').
':' Send intel hex data through SPI/FPGA.
[Options]
'0-9a-fA-F' Intel hex compliant command string (only data and eof record types are supported).
';' Send raw bytes (format similar to intel hex) via SPI/FPGA.
'#' Send raw bytes (no format) via SPI/FPGA.
'C' Set pulse width of clock output.
[Options]
'0-9a-fA-F' Number of tick left out between pulses. (1x byte (2 chars)).
'T' Set onboard time.
[Options]
'0-9a-fA-F' New time (4x byte (8 chars)).

View file

@ -1,58 +0,0 @@
/*
* adc.c
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <avr/io.h>
#include "adc.h"
#include "timer.h"
#define ADC_CHANNEL_MASK 0x1F
#define ADC_CHANNEL_CURRENT ((1 << MUX0) | (1 << MUX1))
#define ADC_CHANNEL_VOLTAGE ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
#define ADC_CHANNEL_CLEAR (~((1 << MUX0) | (1 << MUX1) | (1 << MUX2)))
/* Public */
uint16_t ADC_voltage = 0;
uint16_t ADC_current = 0;
uint16_t ADC_temperature = 0;
void ADC_init(void) {
/* Disable digital input register to save power */
DIDR0 = ~0;
/* Set reference voltage to 2.56V */
ADMUX = (1 << REFS0) | (1 << REFS1)
/* Set input channel to ADC7 */
| (1 << MUX0) | (1 << MUX1) | (1 << MUX2);
/* Enable ADC */
ADCSRA |= (1 << ADEN);
/* Start ADC */
ADCSRA |= (1 << ADSC);
}
void ADC_poll(void) {
/* Alternatingly poll ADC for current and voltage.*/
if (ADCSRA & (1 << ADSC)) {
/* If conversion is still running, do nothing */
return;
} else if ((ADMUX & ADC_CHANNEL_MASK) == ADC_CHANNEL_CURRENT) {
ADC_current = ADC;
ADMUX &= ADC_CHANNEL_CLEAR;
ADMUX |= ADC_CHANNEL_VOLTAGE;
} else if ((ADMUX & ADC_CHANNEL_MASK) == ADC_CHANNEL_VOLTAGE) {
ADC_voltage = ADC;
ADMUX &= ADC_CHANNEL_CLEAR;
/* The next channel is 0, thus ADC_CHANNEL_CLEAR is sufficient */
ADC_check_voltage();
} else if ((ADMUX & ADC_CHANNEL_MASK) == 0x00) {
ADC_temperature = ADC;
ADMUX &= ADC_CHANNEL_CLEAR;
ADMUX |= ADC_CHANNEL_CURRENT;
}
/* Restart ADC */
ADCSRA |= (1 << ADSC);
}

View file

@ -1,28 +0,0 @@
/*
* adc.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef ADC_H_
#define ADC_H_
#include <avr/io.h>
/* Analog-digital-converter unit to measure voltage and check for too high/low
* voltage.
*/
extern uint16_t ADC_voltage;
extern uint16_t ADC_current;
extern uint16_t ADC_temperature;
void ADC_init(void);
void ADC_poll(void);
/* Model specific function */
void ADC_check_voltage(void);
#endif /* ADC_H_ */

View file

@ -1,114 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
import os
import sys
import time
import itertools as it
import serial
def errprint(*args, **kwargs):
kwargs['file'] = sys.stderr
print(*args, **kwargs)
def ichunks(iterable, chunksize=16, fill=None):
n = chunksize
return it.izip(*[it.chain(iterable, it.repeat(fill, n-1))]*n)
def get_device():
device = serial.Serial(baudrate=38400 ,timeout=0.1)
device.setTimeout(0.1)
ports = ['/dev/ttyUSB{}'.format(x) for x in xrange(1,6,2)]
for port in ports:
device.port = port
try:
device.open()
errprint('Connected to port {}'.format(device.name))
break
except serial.SerialException as e:
pass
else:
raise IOError('No device found on ports: {}'.format(' '.join(ports)))
return device
def talk(device, text):
device.write(text + '\n')
response = device.readline()
if response is None:
raise IOError('No response to command: {}'.format(text))
response = response.strip()
return response
def send_bin_safe(device, bin, chunksize=32):
bytecount = chunksize
for chunk in ichunks(bin, chunksize, fill='\00'):
checksum = (bytecount + sum(map(ord, chunk))) & 255
msg = ''.join([';', chr(bytecount), chunk, chr(checksum)])
if response != '.':
errprint('\n', response)
sys.exit(1)
else:
errprint(response, end='')
def send_bin_fast(device, bin):
device.write('#')
device.write(bin)
device.sendBreak()
def send_binary(device, filepath, chunksize=32, protocol='safe'):
with open(filepath, 'rb') as f:
raw_data = f.read()
device.flush()
errprint('FN0')
response = talk(device, 'FN0')
if response:
errprint(response)
time.sleep(0.1)
errprint('FS ->', end='')
respons = talk(device, 'FS')
elif response != '0':
raise IOError('NSTATUS is not 0')
else:
print response
time.sleep(0.1)
errprint('FN1')
response = talk(device, 'FN1')
if response:
errprint(response)
time.sleep(0.1)
errprint('FS ->', end='')
respons = talk(device, 'FS')
elif response != '1':
raise IOError('NSTATUS is not 1')
else:
print response
if protocol == 'safe':
send_bin_safe(device, raw_data, chunksize)
elif protocol == 'fast':
send_bin_fast(device, raw_data)
else:
raise ValueError('protocol must be one of [safe, fast], was {}'.format(protocol))
time.sleep(0.1)
errprint('FC')
respons = talk(device, 'FC')
elif response != '1':
raise IOError('CONFDONE is not 1')
else:
print response
if __name__ == '__main__':
if len(sys.argv) < 2:
print('USAGE: gse_bin2fpga.py filename')
sys.exit()
device = get_device()
filepath = os.path.realpath(sys.argv[1])
send_binary(device, filepath, chunksize=32)

View file

@ -1,98 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
import os
import sys
import time
import itertools as it
import subprocess as sp
import serial
def errprint(*args, **kwargs):
kwargs['file'] = sys.stderr
print(*args, **kwargs)
def talk(device, text):
device.write(text)
return device.readline().strip()
def send_ihex(filepath):
ihex = subprocess.check_output(['./bin2hex', filepath], universal_newlines=True)
device = serial.Serial(baudrate=38400 ,timeout=0.1)
device.setTimeout(0.1)
ports = ['/dev/ttyUSB{}'.format(x) for x in xrange(1,6,2)]
for port in ports:
device.port = port
try:
device.open()
errprint('Connected to port {}'.format(device.name))
except serial.SerialException as e:
pass
else:
raise IOError('No device found on ports: {}'.format(' '.join(ports)))
device.flush()
errprint('FN0')
response = talk(device, 'FN0\n')
if response is None:
raise IOError('No response to command FN0')
time.sleep(0.1)
errprint('FS ->', end='')
respons = talk(device, 'FS\n')
if response is None:
raise IOError('No response to command FS')
elif response != '0':
raise IOError('NSTATUS is not 0')
else:
print response
time.sleep(0.1)
errprint('FN1')
response = talk(device, 'FN1\n')
if response is None:
raise IOError('No response to command FN1')
time.sleep(0.1)
errprint('FS ->', end='')
respons = talk(device, 'FS\n')
if response is None:
raise IOError('No response to command FS')
elif response != '1':
raise IOError('NSTATUS is not 1')
else:
print response
bytecount = chunksize
for line in ihex.split('\n'):
device.write(line)
device.write('\n')
response = device.readline()
if response is None:
raise IOError('No response to binary chunk')
elif response != '.':
errprint('\n', response)
sys.exit(1)
else:
errprint(response, end='')
time.sleep(0.1)
errprint('FC')
respons = talk(device, 'FC\n')
if response is None:
raise IOError('No response to command FC')
elif response != '1':
raise IOError('CONFDONE is not 1')
else:
print response
if __name__ == '__main__':
if len(sys.argv) < 2:
print('USAGE: gse_ihex2fpga.py filename')
sys.exit()
filepath = os.path.realpath(sys.argv[1])
send_ihex(filepath)

View file

@ -1,46 +0,0 @@
/*
* hex.c
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <stdbool.h>
#include <avr/io.h>
#include "hex.h"
#define MASK_LEFT 0b00001111
bool hex2byte(char ch, uint8_t* out) {
/* Return whether `ch` is valid hex (0-9a-fA-F). */
uint8_t tmp = *out;
if ((ch >= '0') && (ch <= '9')) {
*out = ((tmp << 4) | (ch & MASK_LEFT));
return true;
} else if ((ch >= 'A') && (ch <= 'F')) {
*out = ((tmp << 4) | ((ch + 9) & MASK_LEFT));
return true;
} else if ((ch >= 'a') && (ch <= 'f')) {
*out = ((tmp << 4) | ((ch + 9) & MASK_LEFT));
return true;
} else {
return false;
}
}
void byte2hex(uint8_t byte, char* ch0, char* ch1) {
uint8_t tmp = (byte >> 4) & MASK_LEFT;
if (tmp <= 9) {
*ch0 = '0' | tmp;
} else {
*ch0 = ('a' - 1) | (tmp - 9);
}
tmp = byte & MASK_LEFT;
if (tmp <= 9) {
*ch1 = '0' | tmp;
} else {
*ch1 = ('a' - 1) | (tmp - 9);
}
}

View file

@ -1,18 +0,0 @@
/*
* hex.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef HEX_H_
#define HEX_H_
#include <stdbool.h>
#include <avr/io.h>
bool hex2byte(char ch, uint8_t* out);
void byte2hex(uint8_t byte, char* ch0, char* ch1);
#endif /* HEX_H_ */

View file

@ -1,39 +0,0 @@
/*
* io_base.c
*
* Created on: Oct 11, 2014
* Author: Philipp Rasch
* $Id: io_base.h 3243 2014-10-09 10:33:10Z rasch $
*/
#include <stdbool.h>
#include <avr/io.h>
#include "io_base.h"
void send_char(char ch, volatile char* bufferO, volatile uint8_t* nullO) {
//TODO handle overflow
bufferO[*nullO] = ch;
*nullO += 1;
}
void send_string(const char* string, volatile char* bufferO, volatile uint8_t* nullO) {
//TODO handle overflow
while (*string) {
bufferO[*nullO] = *string;
*nullO += 1;
string++;
}
}
void recv_char(char* ch, bool* ret, volatile char* bufferI,
volatile uint8_t* firstI, volatile uint8_t* nullI) {
if (*firstI == *nullI) {
*ret = false;
} else {
*ch = bufferI[*firstI];
*firstI += 1;
*ret = true;
}
}

View file

@ -1,76 +0,0 @@
/*
* io_base.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef IO_BASE_H_
#define IO_BASE_H_
/* Base functions to use with ring buffers and interrupts/polling.
* They are to be wrapped by specialized functions.
* Lots of #defines for functions here, because they produce faster code
* than the pointer mangling required in real functions.
*/
#include <stdbool.h>
/* ------------------------------ Interrupts ------------------------------ */
#define RX_INTERRUPT(bufferI, nullI, reg) \
/* TODO handle overflow */ \
bufferI[nullI] = reg; \
nullI += 1;
#define TX_INTERRUPT(bufferO, firstO, nullO, reg) \
if (firstO != nullO) { \
reg = bufferO[firstO]; \
firstO += 1; \
}
/* ------------------------------ Polling ------------------------------ */
#define RX_POLL(bufferI, nullI, reg, flags, bit) \
if (flags & (1 << bit)) { \
RX_INTERRUPT(bufferI, nullI, reg) \
}
#define TX_POLL(bufferO, firstO, nullO, reg, flags, bit) \
if (flags & (1 << bit)) { \
TX_INTERRUPT(bufferO, firstO, nullO, reg) \
}
/* ------------------------------ To buffer ------------------------------ */
#define SEND_CHAR(ch, bufferO, nullO) \
RX_INTERRUPT(bufferO, nullO, ch)
void send_char(char ch, volatile char* bufferO, volatile uint8_t* nullO);
#define SEND_STRING(string, bufferO, nullO) \
while(*string) { \
RX_INTERRUPT(bufferO, nullO, *string) \
string++; \
}
void send_string(const char* string, volatile char* bufferO, volatile uint8_t* nullO);
/* ------------------------------ From buffer ------------------------------ */
#define RECV_CHAR(ch, success, bufferI, firstI, nullI) \
TX_INTERRUPT(bufferI, firstI, nullI, *ch) \
else { \
success = false; \
} \
success = true;
void recv_char(char* ch, bool* ret, volatile char* bufferI, volatile uint8_t* firstI, volatile uint8_t* nullI);
#define PEEK_CHAR(ch, success, bufferI, firstI, nullI) \
if (firstI != nullI) { \
*ch = bufferI[firstI]; \
success = true; \
} else { \
success = false; \
}
#endif /* IO_BASE_H_ */

View file

@ -1,45 +0,0 @@
/*
* io_spi.c
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <avr/io.h>
#include "io_spi.h"
#include "io_base.h"
/* Public
* TODO: Move to sologse.c ??? */
uint8_t SPI_byte_count = 0;
uint8_t SPI_checksum = 0;
/* Private */
static char S_bufferO[256];
static volatile uint8_t S_firstO, S_nullO = 0x00;
void SPI_init(void) {
PINB |= (1 << PB4); // pull up slave select to avoid leaving master mode
PORTB |= (1 << PB4); // pull up slave select to avoid leaving master mode
SPCR |= (1 << MSTR) // master mode
| (1 << DORD) // send lsb first
| (1 << SPR0) // speed: F_CPU / 16
// | (1 << SPIE) // enable interrupt on serial transfer complete
| (1 << SPE); // enable SPI
}
void SPI_STC_vect(void) {
/* ISR for sending all buffered bytes via SPI. */
TX_INTERRUPT(S_bufferO, S_firstO, S_nullO, SPDR);
}
void SPI_TX_poll(void) {
/* Polling sends first buffered byte and triggers SPI_STC_vect. */
TX_POLL(S_bufferO, S_firstO, S_nullO, SPDR, SPSR, SPIF);
}
void SPI_send_char(char ch) {
/* Send byte to buffer to be sent later. */
SEND_CHAR(ch, S_bufferO, S_nullO);
}

View file

@ -1,28 +0,0 @@
/*
* io_spi.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef IO_SPI_H_
#define IO_SPI_H_
#include <avr/io.h>
/* Interface for piping input from USART to SPI/FPGA */
/* Public (read/write) */
extern uint8_t SPI_byte_count;
extern uint8_t SPI_checksum;
void SPI_init(void);
void SPI_STC_vect(void) __attribute__ ((interrupt));
void SPI_TX_poll(void);
void SPI_send_char(char ch);
#endif /* IO_SPI_H_ */

View file

@ -1,109 +0,0 @@
/*
* io_usart.c
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <stdbool.h>
#include <avr/io.h>
#include "io_usart.h"
#include "io_base.h"
#include "hex.h"
#define USART0_FAST_MODE 2 /* 2 = round(6000000. / (16 * 115200) - 1) */
#define USART0_SLOW_MODE 9 /* 9 = round(6000000. / (16 * 38400) - 1) */
/* Public (read only) */
volatile bool U_frame_error = 0;
/* Private */
static char bufferI[256];
static uint8_t firstI = 0x00;
static volatile uint8_t nullI = 0x00;
static char bufferO[256];
static uint8_t firstO = 0x00;
static volatile uint8_t nullO = 0x00;
void USART0_init(void) {
/* Set baud */
UBRR0 = USART0_SLOW_MODE;
/* Set frame format (8bit, asynchronous, no parity, 1 stop bit) */
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
/* Enable transmitter and receiver */
UCSR0B = (1 << TXEN0) | (1 << RXEN0)
/* Enable interrupt on receive */
| (1 << RXCIE0);
}
void USART0_fast(void) {
/* Set USART to fast mode (115200 bps) .
* DEPREDATED: breaks communication, because of error between system clock
* and IO-speed */
UCSR0B &= ~(1 << RXCIE0);
UBRR0 = USART0_FAST_MODE;
UCSR0B |= (1 << RXCIE0);
}
void USART0_slow(void) {
/* Set USART to slow mode (38400 bps). */
UCSR0B &= ~(1 << RXCIE0);
UBRR0 = USART0_SLOW_MODE;
UCSR0B |= (1 << RXCIE0);
}
void USART0_RX_vect(void) {
/* ISR to write incoming bytes to input buffer. */
U_frame_error = (UCSR0A & (1 << FE0)) && 1;
RX_INTERRUPT(bufferI, nullI, UDR0);
}
void USART0_RX_poll(void) {
/* Poll (nonblocking) USART for incoming byte and write to input buffer. */
RX_POLL(bufferI, nullI, UDR0, UCSR0A, RXC0);
}
void USART0_TX_poll(void) {
/* Poll (nonblocking) output buffer for byte to send. */
TX_POLL(bufferO, firstO, nullO, UDR0, UCSR0A, UDRE0);
}
void USART0_send_char(char ch) {
/* Write byte to output buffer. */
//SEND_CHAR(ch, bufferO, nullO);
send_char(ch, bufferO, &nullO);
}
void USART0_send_hexbyte(uint8_t byte) {
/* Transform byte into 2 hex chars and write them to output buffer. */
char ch0, ch1;
byte2hex(byte, &ch0, &ch1);
//SEND_CHAR(ch0, bufferO, nullO);
//SEND_CHAR(ch1, bufferO, nullO);
send_char(ch0, bufferO, &nullO);
send_char(ch1, bufferO, &nullO);
}
void USART0_send_string(const char* string) {
/* Write string to output buffer. */
//SEND_STRING(string, bufferO, nullO);
send_string(string, bufferO, &nullO);
}
bool USART0_recv_char(char* ch) {
/* Get and remove byte from input buffer.
* Return whether byte could be read. */
bool ret;
//RECV_CHAR(ch, ret, bufferI, firstI, nullI);
recv_char(ch, &ret, bufferI, &firstI, &nullI);
return ret;
}
bool USART0_peek_char(char* ch) {
/* Get byte from buffer without consuming it.
* Return whether byte could be read. */
bool ret;
PEEK_CHAR(ch, ret, bufferI, firstI, nullI);
return ret;
}

View file

@ -1,36 +0,0 @@
/*
* io_usart.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef IO_USART_H_
#define IO_USART_H_
#include <stdbool.h>
#include <avr/io.h>
/* I/O mechanism using 2 separate, ring buffers for input/output,
* interrupts for reception and polling for transmission.
*/
/* Public (read only) */
extern volatile bool U_frame_error;
void USART0_init(void);
void USART0_fast(void);
void USART0_slow(void);
void USART0_RX_vect(void) __attribute__ ((signal));
void USART0_RX_poll(void);
void USART0_TX_poll(void);
void USART0_send_char(char ch);
void USART0_send_string(const char* string);
void USART0_send_hexbyte(uint8_t byte);
bool USART0_recv_char(char* ch);
bool USART0_peek_char(char* ch);
#endif /* IO_USART_H_ */

View file

@ -1,46 +0,0 @@
/*
* Code specific to the mtr3gse
*/
#include <avr/io.h>
#include "adc.h"
#ifndef UNIT
#define UNIT MTR3GSE SN
#endif
#define UNIT_STR1(U) #U
#define UNIT_STR(U) UNIT_STR1(U)
const char* VERSION = UNIT_STR(UNIT);
void ADC_check_voltage(void)
{
static uint16_t ovtimer = 0;
if (ADC_voltage > 0x0360) {
/* Voltage > 5.4V (ADC > 0x0360 ) */
PORTC = (1 << PC1);
} else if (ADC_voltage < 0x02E0) {
/* is undervoltage flag */
// check if massive overvoltage on input => PA0 is high
// in this case UV is measured
if (ADC_temperature > 0x0050) {
// quick and dirty fast RED blinking
ovtimer++;
if (ovtimer < 800) {
PORTC = (1 << PC1);
} else {
PORTC = (0 << PC1);
PORTC = (0 << PC0);
if(ovtimer > 1900)
ovtimer = 0;
}
} else {
/* Voltage < 4.6V (ADC < 0x02E0) */
PORTC = (1 << PC1);
}
} else {
PORTC = (1 << PC0);
}
}

View file

@ -1,33 +0,0 @@
/*
* Code specific to the sologse
*/
#include <avr/io.h>
#include "adc.h"
#include "timer.h"
#ifndef UNIT
#define UNIT SoloGSE SN
#endif
#define UNIT_STR1(U) #U
#define UNIT_STR(U) UNIT_STR1(U)
const char* VERSION = UNIT_STR(UNIT);
void ADC_check_voltage(void)
{
if (ADC_voltage > 0x02D5) {
/* Voltage > 29V (ADC > 0x02D5 [0x02DA measured]) */
if (TC1_blink) {
PORTC = (1 << PC1);
} else {
PORTC = 0;
}
} else if (ADC_voltage < 0x028A) {
/* Voltage < 26V (ADC < 0x028A) */
PORTC = (1 << PC1);
} else {
PORTC = (1 << PC0);
}
}

View file

@ -1,573 +0,0 @@
/*
* sologse.c
*
* Created on: Jan 21, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <stdbool.h>
#include <avr/io.h>
#include <avr/cpufunc.h> /* _NOP() */
#include <avr/interrupt.h> /* reti(), sei(), cli() */
#include "hex.h"
#include "io_usart.h"
#include "io_spi.h"
#include "timer.h"
#include "adc.h"
/* ------------------------------ CONSTANTS ------------------------------ */
extern const char * VERSION;
const char* e_newline = "ERROR: No newline";
const char* e_syntax = "ERROR: Syntax";
/* ------------------------------ SPECIAL SEND ------------------------------
* Some convenience functions to send special information about the current
* state of the device.
*/
void send_ports(void) {
/* The values of the 4 input ports as a 32 bit hex number. */
USART0_send_string("0x");
USART0_send_hexbyte(PINA);
USART0_send_hexbyte(PINB);
USART0_send_hexbyte(PINC);
USART0_send_hexbyte(PIND);
}
void send_time(void) {
/* The current value of the internal clock as a 32 bit hex number. */
char ch0, ch1;
TC1_time_get();
USART0_send_string("0x");
for (uint8_t i = 0; i < 4; i++) {
byte2hex(TC1_time_buffer[i], &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
}
}
void send_adc(void) {
/* The last measurements by the adc. Three 16 bit hex numbers seperated by
* whitespace. */
char ch0, ch1;
USART0_send_string("0x");
byte2hex(ADC_voltage >> 8, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
byte2hex(ADC_voltage, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
USART0_send_char(' ');
USART0_send_string("0x");
byte2hex(ADC_current >> 8, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
byte2hex(ADC_current, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
USART0_send_char(' ');
USART0_send_string("0x");
byte2hex(ADC_temperature >> 8, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
byte2hex(ADC_temperature, &ch0, &ch1);
USART0_send_char(ch0);
USART0_send_char(ch1);
}
/* ------------------------------ STATE ------------------------------
* A state machine to handle the input.
*/
static inline void input_handler(char input);
void state_idle(char input);
void state_cmd_done(char input);
void state_error(char input);
void state_info(char input);
void state_mode_select(char input);
void state_fpga(char input);
void state_pipe_ihex(void);
void state_pipe_bin(char input);
void state_pipe_bin_fast(char input);
void state_set_1hz_clk(char input);
void state_set_time(void);
/* All Possible states encoded in 8 bit. */
#define CTRL_IDLE 0x00
#define CTRL_CMD_DONE 0x01
#define CTRL_ERROR 0x03
#define CTRL_INFO_0 0xF0
#define CTRL_MODE_SEL_0 0x10
#define CTRL_FPGA_0 0x30
#define CTRL_PIPE_IHEX_0 0x20
#define CTRL_PIPE_BIN_0 0x60
#define CTRL_PIPE_BIN_1 0x61
#define CTRL_SET_1HZ_CLK_0 0x40
#define CTRL_SET_TIME_0 0x50
uint8_t state = CTRL_IDLE;
uint8_t hex_input = 0x00;
bool input_is_hex = false;
static inline void input_handler(char input) {
/* Use a system of state machines to handle input.
* For convenience all input is also assumed to be characters of a hex
* number and converted to bytes (2 chars result in 1 byte). Substates may
* access the converted input through the variable 'hex_input' and check if
* the input was valid hex through 'input_is_hex'.
*/
input_is_hex = hex2byte(input, &hex_input);
switch (state) {
case CTRL_IDLE:
state_idle(input);
break;
case CTRL_CMD_DONE:
state_cmd_done(input);
break;
case CTRL_ERROR:
state_error(input);
break;
case CTRL_INFO_0:
state_info(input);
break;
case CTRL_MODE_SEL_0:
state_mode_select(input);
break;
case CTRL_FPGA_0:
state_fpga(input);
break;
case CTRL_PIPE_IHEX_0:
state_pipe_ihex();
break;
case CTRL_PIPE_BIN_0:
state_pipe_bin(input);
break;
case CTRL_SET_1HZ_CLK_0:
state_set_1hz_clk(input);
break;
case CTRL_SET_TIME_0:
state_set_time();
break;
}
}
/* Definition of symbols associated with different states. */
#define SYMBOL_USART 'U'
#define SYMBOL_ADC 'P'
#define SYMBOL_TIME 'T'
#define SYMBOL_1HZ_CLK 'C'
#define SYMBOL_FPGA 'F'
#define SYMBOL_SPI 'S'
/* Some states may enable time triggerd logging */
#define LOGGING_ADC 0x01
uint8_t logging_enabled = 0x00;
/* Some states may require internal state of their own during execution.
* This substate is reset each time the machine returns to the IDLE state.
*/
uint8_t substate = 0;
void state_idle(char input) {
/* Reset substate to 0 and start functions */
substate = 0;
switch (input) {
case 'I':
state = CTRL_INFO_0;
break;
case 'M':
state = CTRL_MODE_SEL_0;
break;
case SYMBOL_FPGA:
state = CTRL_FPGA_0;
break;
case ':':
state = CTRL_PIPE_IHEX_0;
break;
case ';':
state = CTRL_PIPE_BIN_0;
break;
case '#':
state = CTRL_PIPE_BIN_1;
break;
case SYMBOL_1HZ_CLK:
state = CTRL_SET_1HZ_CLK_0;
break;
case SYMBOL_TIME:
state = CTRL_SET_TIME_0;
break;
default:
break;
}
}
void state_cmd_done(char input) {
/* Check for newline at end of command, goto state_error if no newline.
* Every command except state_idle and state_error should lead to this state
* at the end of its execution, if no errors occurred.
*/
switch (input) {
case '\n':
case '\r':
USART0_send_char('\n');
state = CTRL_IDLE;
break;
default:
USART0_send_string(e_newline);
state = CTRL_ERROR;
break;
}
}
void state_error(char input) {
/* Wait for newline to avoid any further command execution on faulty input.
* Every command except state_idle and state_error should lead to this state
* if an error occurs during execution.
*/
switch (input) {
case '\n':
case '\r':
USART0_send_char('\n');
state = CTRL_IDLE;
break;
}
}
void state_info(char input) {
/* Send info about various things */
switch (input) {
case 'I':
send_ports();
state = CTRL_CMD_DONE;
break;
case SYMBOL_ADC:
send_adc();
state = CTRL_CMD_DONE;
break;
case SYMBOL_TIME:
send_time();
state = CTRL_CMD_DONE;
break;
case 'V':
USART0_send_string(VERSION);
state = CTRL_CMD_DONE;
break;
default:
USART0_send_string(e_syntax);
state = CTRL_ERROR;
break;
}
}
void state_mode_select(char input) {
/* Change settings of some modules */
switch (substate) {
case 0:
switch (input) {
case SYMBOL_ADC:
substate = 1;
break;
case SYMBOL_USART:
substate = 2;
break;
case SYMBOL_SPI:
substate = 3;
break;
case SYMBOL_TIME:
/* Sync onboard clock */
TCNT1 = 0;
state = CTRL_CMD_DONE;
break;
default:
USART0_send_string(e_syntax);
state = CTRL_ERROR;
break;
}
break;
case 1:
/* Enable/disable continuous ADC logging */
if (input == '0') {
logging_enabled &= ~LOGGING_ADC;
state = CTRL_CMD_DONE;
} else if (input == '1') {
logging_enabled |= LOGGING_ADC;
state = CTRL_CMD_DONE;
} else {
USART0_send_string(e_syntax);
state = CTRL_ERROR;
}
USART0_send_char(input);
break;
case 2:
/* Change USART speed */
if (input == '0') {
USART0_slow();
USART0_send_char(input);
state = CTRL_CMD_DONE;
} else if (input == '1') {
USART0_fast();
USART0_send_char(input);
state = CTRL_CMD_DONE;
} else {
USART0_send_string(e_syntax);
state = CTRL_ERROR;
}
break;
case 3:
/* Change SPI data order */
if (input == 'L') {
SPCR &= ~(1 << DORD);
USART0_send_char(input);
state = CTRL_CMD_DONE;
} else if (input == 'M') {
SPCR |= (1 << DORD);
USART0_send_char(input);
state = CTRL_CMD_DONE;
} else {
USART0_send_string(e_syntax);
state = CTRL_ERROR;
}
break;
}
}
void state_fpga(char input) {
/* Get/set different variables concerning the FPGA programmer */
switch (substate) {
case 0:
switch (input) {
case 'N':
/* Goto: set NCONFIG */
substate = 1;
break;
case 'C':
/* Read CONFDONE */
USART0_send_char(PIND & (1 << PD3) ? '1' : '0');
state = CTRL_CMD_DONE;
break;
case 'S':
/* Read NSTATUS */
USART0_send_char(PIND & (1 << PD2) ? '1' : '0');
state = CTRL_CMD_DONE;
break;
default:
USART0_send_string(e_syntax);
state = CTRL_ERROR;
break;
}
break;
case 1:
/* Set NCONFIG */
substate = '0';
if (PORTD & (1 << PD4)) {
substate = '1';
}
switch (input) {
case '0':
PORTD &= ~(1 << PD4);
USART0_send_char(substate);
USART0_send_string(" > ");
USART0_send_char(input);
state = CTRL_CMD_DONE;
break;
case '1':
PORTD |= (1 << PD4);
USART0_send_char(substate);
USART0_send_string(" > ");
USART0_send_char(input);
state = CTRL_CMD_DONE;
break;
default:
USART0_send_string(e_syntax);
state = CTRL_ERROR;
break;
}
break;
}
}
void state_pipe_ihex(void) {
/* Convert ihex to binary and send via SPI */
if (!input_is_hex) {
USART0_send_string("iHEX Error: column=");
USART0_send_hexbyte(substate);
state = CTRL_ERROR;
return;
}
if (!substate) {
SPI_checksum = 0;
SPI_byte_count = 0;
}
substate++;
if (substate & 1)
return;
SPI_checksum += hex_input;
if (substate == 2)
SPI_byte_count = hex_input;
if (substate >= 10 && substate < 10 + 2 * SPI_byte_count)
SPI_send_char(hex_input);
if (substate == 10 + 2 * SPI_byte_count) {
if (SPI_checksum == 0) {
USART0_send_char('.');
state = CTRL_CMD_DONE;
} else {
USART0_send_string("Checksum Error");
state = CTRL_ERROR;
}
}
}
void state_pipe_bin(char input) {
/* Send binary data via SPI */
if (substate == 0) {
SPI_byte_count = input;
SPI_checksum = input;
} else if (substate <= SPI_byte_count) {
SPI_send_char(hex_input);
SPI_checksum += input;
} else if (SPI_checksum + input == 0) {
USART0_send_char('.');
state = CTRL_CMD_DONE;
} else {
USART0_send_string("Checksum Error");
state = CTRL_ERROR;
}
substate++;
}
void state_pipe_bin_fast(char input) {
/* Send binary data without checksums */
if (U_frame_error) {
USART0_send_char('\n');
state = CTRL_IDLE;
} else {
TC1_time_get();
substate = TC1_time_buffer[3];
SPI_send_char(input);
}
}
void state_set_time(void) {
/* Set onboard 32bit clock */
substate++;
if (!input_is_hex) {
USART0_send_string(e_syntax);
state = CTRL_ERROR;
return;
} else if (substate & 1) {
return;
} else if (substate <= 8) {
TC1_time_buffer[substate / 2 - 1] = hex_input;
}
if (substate >= 8) {
TC1_time_set();
state = CTRL_CMD_DONE;
}
}
void state_set_1hz_clk(char input) {
/* Set pulse width */
substate++;
if (!input_is_hex) {
/* Raise error when input is not hex. */
USART0_send_string(e_syntax);
state = CTRL_ERROR;
} else if (substate == 2) {
TC1_pulse_width = hex_input;
USART0_send_string("0x");
USART0_send_hexbyte(hex_input);
} else if (substate == 3) {
if (input == '\n' || input == '\r') {
/* Custom end-of-command handling, because the command has variable
* length. */
USART0_send_char('\n');
state = CTRL_IDLE;
} else if (input == '!') {
TC1_counter = 1;
state = CTRL_CMD_DONE;
} else {
USART0_send_string(e_syntax);
state = CTRL_ERROR;
}
}
}
/* ------------------------------ TIMED ACTIONS ------------------------------
* Things that need to be done once each x seconds.
*/
void log_adc(void);
void pipe_bin_fast_timeout(void);
void do_each_second(void) {
/* Allow low priority functions to be called only once per second. */
if (logging_enabled & LOGGING_ADC) {
log_adc();
}
if (state == CTRL_PIPE_BIN_1) {
pipe_bin_fast_timeout();
}
}
void log_adc(void) {
/* Send current time and ADC readings of voltage and current. */
send_time();
USART0_send_char(' ');
send_adc();
USART0_send_char('\n');
}
void pipe_bin_fast_timeout(void) {
/* Wait at least >1 second after last byte was received, before killing the
* transmission via fast binary piping.*/
TC1_time_get();
if (TC1_time_buffer[3] > substate + 1) {
USART0_send_char('\n');
state = CTRL_IDLE;
}
}
/* ------------------------------ MAIN ------------------------------ */
int main(int argc, char **argv) {
/* Set output pins */
DDRB |= (1 << PB4) | (1 << PB5) | (1 << PB7); // ~SS/DATA0/DCLK
DDRC |= (1 << PC0) | (1 << PC1); // LED-PWR_GREEN/RED
DDRD |= (1 << PD4) | (1 << PD5); // NCONFIG/1HZ_CLK
/* Start all components in order of importance */
TC1_init();
ADC_init();
USART0_init();
SPI_init();
/* Setup done. Globally enable interrupts */
sei();
USART0_send_string(VERSION);
USART0_send_char('\n');
/* Main loop */
char input = 0x00;
bool toggle_each_second = false;
while (1) {
ADC_poll();
USART0_TX_poll();
USART0_TX_poll();
SPI_TX_poll();
if (USART0_recv_char(&input)) {
input_handler(input);
}
if (toggle_each_second != TC1_blink) {
toggle_each_second ^= true;
do_each_second();
}
}
return 0;
}

View file

@ -1,306 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
import itertools as itt
import contextlib
import serial
def errprint(*args, **kwargs):
'''Always print to stderr.'''
kwargs['file'] = sys.stderr
print(*args, **kwargs)
def ichunks(iterable, chunksize=16, fill=None):
'''Iterator to split an iterable into parts of lenght `chunksize`.'''
n = chunksize
return itt.izip(*[itt.chain(iterable, itt.repeat(fill, n-1))]*n)
@contextlib.contextmanager
def ignored(*errors):
'''Ignore specified errors.'''
try:
yield
except errors as e:
pass
class SoloGSE(serial.Serial):
'''Serial interface with special methods for easier communication.'''
def __init__(self, baudrate=38400):
super(self.__class__, self).__init__(baudrate=baudrate, timeout=0.1)
self.setTimeout(0.1)
def open(self, port=None):
if port is not None:
self.setPort(port)
super(self.__class__, self).open()
def talk(self, command):
self.write(command)
self.write('\n')
response = self.readline()
if response is None:
raise IOError('No response to command: {}'.format(command))
return response.strip()
def sendBin(self, data):
bytecount = len(data)
checksum = (bytecount + sum(map(ord, data))) & 255
msg = ''.join([';', chr(bytecount), data, chr(checksum), '\n'])
response = self.talk(msg)
return response
def sendBinFast(self, data):
self.write('#')
self.write(data)
self.sendBreak()
response = self.readline()
if response is None:
raise IOError('No response to command: #...')
return response
def sendIHex(self, data):
def hexNum(number):
return hex(number)[2:]
bytecount = len(data)
checksum = hexNum((bytecount + sum(map(ord, data))) & 255)
data = ''.join(map(hexNum, map(ord, data)))
msg = ''.join([':', hexNum(bytecount), '000000', data, checksum, '\n'])
response = self.talk(msg)
return response
def isendChunks(self, data, method, chunksize=16):
for chunk in ichunks(data, chunksize, fill='\00'):
yield method(chunk)
if method == self.sendIHex:
yield self.talk(':00000001FF\n')
if __name__ == '__main__':
import io
import sys
import time
import argparse
@contextlib.contextmanager
def redirect_stderr():
'''Redirect stderr to a temporary buffer.'''
tmp, sys.stderr = sys.stderr, io.BytesIO()
yield sys.stderr
sys.stderr = tmp
@contextlib.contextmanager
def print_errors(*errors):
try:
yield
except errors as e:
errprint(e)
SOLOGSE = SoloGSE()
def f_send(args):
if args.file:
f = argparse.FileType('rw')(args.data)
with contextlib.closing(f):
args.data = f.read()
# Prepare device
SOLOGSE.flushInput()
SOLOGSE.talk('FN0')
time.sleep(0.1)
response = SOLOGSE.talk('FS')
if response != '0':
errprint('ERROR: NSTATUS should be 0, is {}'.format(response))
time.sleep(0.1)
SOLOGSE.talk('FN1')
time.sleep(0.1)
response = SOLOGSE.talk('FS')
if response != '1':
errprint('ERROR: NSTATUS should be 1, is {}'.format(response))
# Send data
if args.format == 'ihex':
for response in SOLOGSE.isendChunks(args.data, SOLOGSE.sendIHex):
errprint(response, end='')
elif args.format == 'bin':
for response in SOLOGSE.isendChunks(args.data, SOLOGSE.sendBin):
errprint(response, end='')
elif args.format == 'fast':
SOLOGSE.sendBinFast(args.data)
# Finalize transfer
time.sleep(0.1)
response = SOLOGSE.talk('FC')
if response != '1':
errprint('ERROR: CONFDONE should be 1, is {}'.format(response))
def f_info(args):
mapping = {
'pins': 'II',
'power': 'IP',
'time': 'IT',
'version': 'IV'}
response = SOLOGSE.talk(mapping[args.topic])
if response:
errprint(' ', response)
def f_mode(args):
if args.power_log == 'true':
response = SOLOGSE.talk('MP1')
errprint(' power log:', response)
elif args.power_log == 'false':
response = SOLOGSE.talk('MP0')
errprint(' power log:', response)
# if args.usart_speed == 'fast':
# response = SOLOGSE.talk('MU1')
# errprint(' usart speed:', response)
# elif args.usart_speed == 'slow':
# response = SOLOGSE.talk('MU0')
# errprint(' usart speed:', response)
def f_fpga(args):
if args.data_order == 'lsb':
response = SOLOGSE.talk('MFL')
errprint(' data order:', response)
elif args.data_order == 'msb':
response = SOLOGSE.talk('MFM')
errprint(' data order:', response)
if args.nconfig == '0':
response = SOLOGSE.talk('FN0')
errprint(' NCONFIG:', response)
elif args.nconfig == '1':
response = SOLOGSE.talk('FN1')
errprint(' NCONFIG:', response)
if args.nstatus:
response = SOLOGSE.talk('FS')
errprint(' NSTATUS:', response)
if args.confdone:
response = SOLOGSE.talk('FC')
errprint(' CONFDONE:', response)
def f_time(args):
if args.sync:
response = SOLOGSE.talk('MU0')
errprint(' clock synced')
if args.set:
response = SOLOGSE.talk('T{}'.format(args.set))
errprint(' time set.', response)
if args.delay:
i = '!' if args.immediate else ''
response = SOLOGSE.talk('C{}{}'.format(args.delay, i))
errprint(' delay set.', response)
if not (args.sync or args.set or args.delay or args.immediate):
response = SOLOGSE.talk('IT')
errprint('', response)
PARSER = argparse.ArgumentParser()
def f_interactive(args):
while True:
cmdline = raw_input(' ').strip().split()
if not cmdline:
continue
if cmdline[0] == 'exit':
sys.exit(0)
with redirect_stderr():
with ignored(SystemExit):
args = PARSER.parse_args(cmdline)
sys.stderr.seek(0)
error = sys.stderr.readlines()
if error:
errprint(' ', ' '.join(error[-1].split()[1:]))
else:
args.func(args)
PARSER.add_argument('--port', '-p', default=None,
help='port to connect to. By default ttyUSB[1,3,5] are tested.')
subparsers = PARSER.add_subparsers()
sender = subparsers.add_parser('send', help='send binary data to fpga.')
sender.add_argument('format', choices=['ihex', 'bin', 'fast'],
help='format to use for transmission.')
sender.add_argument('data',
help='binary data to send (or file path if [-f, --file] is present).')
sender.add_argument('--file', '-f', action='store_true',
help='read file at path provided by `data`.')
sender.set_defaults(func=f_send)
info = subparsers.add_parser('info', help='show info about the device.')
info.add_argument('topic', choices=['pins', 'power', 'time', 'version'],
help='topic to show info about.')
info.set_defaults(func=f_info)
mode = subparsers.add_parser('mode',
help='change modes of certain modules.')
mode.add_argument('adc_log', choices=['true', 'false'], #nargs='?',
metavar='power logging: true, false',
help='enable/disable voltage and current logging. (default: false)')
# FIXME fast speed breaks usart, because timing error is too large.
# mode.add_argument('usart_speed', choices=['slow', 'fast'], nargs='?',
# metavar='usart speed: slow, fast',
# help='change usart_speed (38400, 115200). (default:slow)')
mode.set_defaults(func=f_mode)
fpga = subparsers.add_parser('fpga',
help='get/set state of the fpga programmer.')
fpga.add_argument('--data_order', '-o', choices=['lsb', 'msb'],
help='switch between sending least/most significant bit first. (default: lsb)')
fpga.add_argument('--nstatus', '-s', action='store_true',
help='show NSTATUS.')
fpga.add_argument('--confdone', '-c', action='store_true',
help='show CONFDONE.')
fpga.add_argument('nconfig', choices=['0', '1'], nargs='?',
metavar='NCONFIG: 0,1', help='set NCONFIG.')
fpga.set_defaults(func=f_fpga)
clock = subparsers.add_parser('clock',
help='get/set onboard time and HET/EPT clock delay.')
clock.add_argument('--sync', '-s', action='store_true',
help='reset internal counter to recognize this instant as the start of a new second.')
clock.add_argument('--set' '-t', default=None,
help='set clock (32bit hex).')
clock.add_argument('--delay', '-d', default=None,
help='set delay of HET/EPT in seconds (8bit hex).')
clock.add_argument('--immediadte', '-i', action='store_true',
help='apply delay immediately')
clock.set_defaults(func=f_time)
interactive = subparsers.add_parser('interactive')
interactive.set_defaults(func=f_interactive)
if len(sys.argv) < 2:
sys.argv.append('interactive')
args = PARSER.parse_args()
with contextlib.closing(SOLOGSE):
if args.port is None:
ports = ['/dev/ttyUSB{}'.format(x) for x in xrange(1,7,2)]
for port in ports:
try:
SOLOGSE.open(port)
errprint('Connected to port {}'.format(SOLOGSE.name))
break
except serial.SerialException as e:
errprint(e)
else:
#errprint('No device found on ports: {}'.format(' '.join(ports)))
raise SystemExit(1)
else:
try:
SOLOGSE.open(args.port)
errprint('Connected to port {}'.format(SOLOGSE.name))
except serial.SerialException as e:
errprint(e)
raise SystemExit(1)
with print_errors(KeyboardInterrupt, Exception):
args.func(args)

View file

@ -1,86 +0,0 @@
/*
* timer.c
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#include <stdbool.h>
#include <avr/io.h>
#include "timer.h"
#define TC1_TOP 0xb71b // Perfect timing
#define TC1_COM1A_ACTIVE ((1 << COM1A1) | (1 << COM1A0))
#define TC1_COM1A_INACTIVE (~((1 << COM1A1) | (1 << COM1A0)))
/* Public (read/write) */
uint8_t TC1_pulse_width = 1;
volatile uint8_t TC1_counter = 1;
uint8_t TC1_time_buffer[4];
/* Public (read only) */
volatile bool TC1_blink = 0;
/* Private */
static volatile uint32_t TC1_time = 0;
void TC1_init(void) {
/* Pull output pin low to avoid any unwanted outputs.*/
PORTD &= (~(1 << PD5));
/* Set TOP (ICR1) and compare register (OCR1A). Pulse goes from (TOP - 1) to
* (TOP + 1) and is therefore 2 Ticks long. */
ICR1 = TC1_TOP;
OCR1A = TC1_TOP - 1;
/* Set compare output mode for channel A to set on up count, clear on down
* count */
TCCR1A |= TC1_COM1A_ACTIVE;
/* Set mode to 'Phase and frequency correct PWM' with ICR1 as TOP */
TCCR1B |= (1 << WGM13)
/* Set prescaler to 64 */
| ((1 << CS11) | (1 << CS10));
/* Enable interrupt on BOTTOM (TOV1) */
TIMSK1 |= (1 << TOIE1);
/* Enable Timer/Counter1 */
PRR &= ~(1 << PRTIM1);
}
void TIMER1_OVF_vect(void) {
/* Interrupt to toggle 'blink', increment 'time' change 'pulsewidth'
* exactly once per second. */
TC1_blink ^= true;
TC1_time++;
if (TC1_pulse_width == 0) {
TCCR1A &= TC1_COM1A_INACTIVE;
TC1_counter = 1;
} else {
if (TC1_counter == 1) {
TCCR1A |= TC1_COM1A_ACTIVE;
TC1_counter = TC1_pulse_width;
} else {
TCCR1A &= TC1_COM1A_INACTIVE;
TC1_counter--;
}
}
}
void TC1_time_get(void) {
/* Write system time to publicly accessible buffer.
* Necessary to avoid conflicts if time is updated while reading. */
uint8_t* ptr = (uint8_t*) &TC1_time;
TIMSK1 &= ~(1 << TOIE1);
for (uint8_t i = 0; i < 4; i++) {
TC1_time_buffer[3 - i] = *(ptr + i);
}
TIMSK1 |= (1 << TOIE1);
}
void TC1_time_set(void) {
/* Set system time from publicly accessible buffer.
* Necessary to avoid conflicts if time is updated while writing. */
uint8_t* ptr = (uint8_t*) &TC1_time;
TIMSK1 &= ~(1 << TOIE1);
for (uint8_t i = 0; i < 4; i++) {
*(ptr + i) = TC1_time_buffer[3 - i];
}
TIMSK1 |= (1 << TOIE1);
}

View file

@ -1,33 +0,0 @@
/*
* timer.h
*
* Created on: Jun 15, 2014
* Author: Philipp Rasch
* $Id$
*/
#ifndef TIMER_H_
#define TIMER_H_
#include <stdbool.h>
#include <avr/io.h>
/* Timer for generating between 1Hz and 1/256Hz clock output to drive the
* serial connection.
*/
/* Public (read/write) */
extern uint8_t TC1_pulse_width;
extern volatile uint8_t TC1_counter;
extern uint8_t TC1_time_buffer[4];
/* Public (read only) */
extern volatile bool TC1_blink;
void TC1_init(void);
void TIMER1_OVF_vect(void) __attribute__ ((interrupt));
void TC1_time_get(void);
void TC1_time_set(void);
#endif /* TIMER_H_ */

View file

@ -1,78 +0,0 @@
#include <avr/io.h>
#define SPSR_IF (1<<SPIF)
static inline void spi_slave_init()
{
SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA);
SPSR;
SPDR;
}
static inline unsigned char spi_slave_Rx_status()
{
return SPSR & SPSR_IF && !(SPDR & 0x80);
}
static inline void spi_slave_Rx(unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
register unsigned char b;
do {
while (!(SPSR & SPSR_IF));
SPDR = 0xff;
b = SPDR;
} while (b&0x80);
*d++ = b;
while (--n) {
while (!(SPSR & SPSR_IF));
SPDR = 0xff;
*d++ = SPDR;
}
}
extern volatile unsigned char wdt_tick;
static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
register unsigned char b;
do {
while (!(SPSR & SPSR_IF));
wdt_tick = 0;
SPDR = 0xff;
b = SPDR;
} while (b&0x80);
*d++ = b;
while (--n) {
while (!(SPSR & SPSR_IF));
SPDR = 0xff;
*d++ = SPDR;
}
return wdt_tick;
}
static inline void spi_slave_Tx(const unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
while (n) {
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF));
SPDR = b;
n--;
}
}
static inline void int2frame(unsigned int i, unsigned char *f)
{
f[0] = i;
f[1] = i>>8;
}
static inline unsigned int frame2int(unsigned char *f)
{
return f[1]<<8 | f[0];
}
#define INT2FRAME(i) ((unsigned char []){i, i>>8})

View file

@ -1,117 +0,0 @@
#ifndef SPDR
# define SPDR *(volatile unsigned char *)0x2f
# define SPSR *(volatile unsigned char *)0x2e
# define SPIC_INT_vect __vector_24
#endif
#define spi_slave_isr SPIC_INT_vect
#define SPSR_IF 0x80
static unsigned char TxBuf[256] = {[0]=0}, RxBuf[256];
static unsigned char TxWptr = 0, TxRptr = 0, RxWptr = 0, RxRptr = 0;
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
// TODO: use AVR ISR macro with proper vector name
// The SPI ISR will load a new Tx frame very fast, before the next
// SCLK comes in. Then is will fetch teh Rx frame, which can be done
// until the next frame is finished.
__attribute__ ((signal, used, externally_visible))
void spi_slave_isr(void)
{
unsigned char sr = SPSR;
// avoid the jump for the likely case that
// SPIF is set
if (likely(sr & SPSR_IF)) {
// The empty Buffer shall always present a zero
// under the read pointer
SPDR = TxBuf[TxRptr];
// Here we are done with the urgent stuff, now we have
// seven more SCLK cycles to spend.
// Inrcement the read point when the buffer was not empty
if (TxRptr != TxWptr)
TxRptr++;
// Incoming frames are stored when they are non-zero, or when
// they go to an odd address. This way we can receive
// 16-bit frames.
unsigned char d = SPDR;
if (d || RxWptr&1)
RxBuf[TxWptr++] = d;
}
}
static inline unsigned char disable_irq(void) { __asm__(" cli\n"); return 0; }
static inline void enable_irq(unsigned char f) { __asm__(" sei\n"); }
// We submit n bytes atomically, either completely or not al all.
unsigned char spi_slave_Tx(unsigned char d[], unsigned char n)
{
if (unlikely(!n))
return 0;
unsigned char p = TxWptr+1;
unsigned char i = 1;
// Save the tail first, which can be done at leisure, because
// it does not change the state of the buffer.
while (i<n && p != TxRptr)
TxBuf[p++] = d[i++];
// If all did not fit, we abort.
if (unlikely(i<n || p==TxRptr))
return 0;
// Load a zero after the message, which will be send when
// the buffer runs empty.
TxBuf[p] = 0;
// Now we need to disable interrupts, because the store of the
// First byte and the increment of the write pointer
// must be atomically. Else the first byte may be sent twice or not al all,
// depending on the order we to the two stores.
// preload all we need before disabling ints
volatile register unsigned char *bb = TxBuf + TxWptr;
register unsigned char b = d[0];
unsigned char iflg = disable_irq();
*bb = b;
TxWptr = p;
enable_irq(iflg);
return i;
}
unsigned char spi_slave_Rx(unsigned char d[], unsigned char n)
{
unsigned char i = 0;
while (i<n && RxRptr != RxWptr)
d[i++] = RxBuf[RxRptr++];
return i;
}
void spi_slave_Tx_sync(unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
while (n) {
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF));
SPDR = b;
n--;
}
}
void spi_slave_Rx_sync(unsigned char d[], unsigned char n)
{
register unsigned char b = 0;
do {
while (!(SPSR & SPSR_IF));
b = SPDR;
} while (!b);
*d++ = b;
while (--n) {
while (!(SPSR & SPSR_IF));
*d++ = SPDR;
}
}

View file

@ -1,8 +1,9 @@
@s/if pres > 1000 and pres < 5000 and temp < 3432 and temp > 2832: s/exec "SAFE.RC" 5 @s/if pres > 1000 and pres < 5000 and temp < 3432 and temp > 2432: s/exec "SAFE.RC" 5
@s/if pres[1] > 2000 or temp[1] > 3432 or temp[1] < 2832: s/exit @s/if pres[1] > 2000 or pres[1] < -100 or temp[1] > 3432 or temp[1] < 2432: s/exit
@v M = M+1 @v M = M+1
@s/if M < 10 or F != 1: s/exit @s/if M < 10 or F != 1: s/exit
@script/spy "DESCENT.SPY"
@e/info "ASCENTED p=", pressure
@var F=2 @var F=2
@var N=0 @var N=0
@e/info "ASCENTED p=%d", pressure[1]
@script/spy "DESCENT.SPY"
@e not reached, spy file is closed

View file

@ -1,3 +1,4 @@
@s/if pres > 1000 and pres < 5000 and temp < 3432 and temp > 2832: s/exec "SAFE.RC" 5 @s/if pres > 1000 and pres < 5000 and temp < 3432 and temp > 2432: s/exec "SAFE.RC" 5
@s/if pres[1]<8000 or pres[1]>11000 or temp[1] > 3432 or temp[1] < 2832: s/exit @s/if pres[1]<8000 or pres[1]>11000 or temp[1] > 3432 or temp[1] < 2432: s/exit
s/exec "SAFE.RC" 3 s/exec "SAFE.RC" 3
@e not reached, spy file is closed

View file

@ -1,7 +1,7 @@
eth/source/ip 134.245.70.129 eth/source/ip 172.16.18.111
echo eth/dest: grautvornix echo eth config CHAOS
@eth/dest/str/mac/ip/port 18:31:bf:df:0c:34 134.245.70.130 1112 @eth/dest/str/mac/ip/port 3c:97:0e:ce:30:48 172.16.18.110 1112
@eth/dest/mes/mac/ip/port 18:31:bf:df:0c:34 134.245.70.130 1113 @eth/dest/mes/mac/ip/port 3c:97:0e:ce:30:48 172.16.18.110 1113
@eth/init/full @eth/init/full
@s/if errno>=500: s/exit @s/if errno>=500: s/exit
@var/set eth_verbosity = 4 @var/set eth_verbosity = 4

View file

@ -39,24 +39,24 @@
@irena/windows 2 5 8 11 @irena/windows 2 5 8 11
@var/set mV=14000 @var/set mV=14000
@v T=0 @v T=0
@v/set Z[13] = 14*mV # A1H @v/set Z[13] = 10*mV # A1H
@v/set Z[12] = 10*mV # A1L @v/set Z[12] = 10*mV # A1L
@v/set Z[10] = 20*mV # A2H @v/set Z[10] = 15*mV # A2H
@v/set Z[ 9] = 10*mV # A2L @v/set Z[ 9] = 10*mV # A2L
@v/set Z[17] = 50*mV # B @v/set Z[17] = 50*mV # B
@v/set Z[ 7] = 14*mV # C1H @v/set Z[ 7] = 10*mV # C1H
@v/set Z[ 6] = 10*mV # C1L @v/set Z[ 6] = 10*mV # C1L
@v/set Z[ 4] = 20*mV # C2H @v/set Z[ 4] = 15*mV # C2H
@v/set Z[ 3] = 10*mV # C2L @v/set Z[ 3] = 10*mV # C2L
@v/set Z[16] = 20*mV # D1H @v/set Z[16] = 20*mV # D1H
@v/set Z[15] = 20*mV # D1L @v/set Z[15] = 20*mV # D1L
@v/set Z[14] = 20*mV # D2H @v/set Z[14] = 20*mV # D2H
@v/set Z[11] = 20*mV # D2L @v/set Z[11] = 20*mV # D2L
@v/set Z[ 1] = 25*mV # EH @v/set Z[ 1] = 10*mV # EH
@v/set Z[ 0] = 20*mV # EL @v/set Z[ 0] = 10*mV # EL
@v/set Z[ 8] = 10*mV # E1 @v/set Z[ 8] = 8*mV # E1
@v/set Z[ 5] = 10*mV # E2 @v/set Z[ 5] = 8*mV # E2
@v/set Z[ 2] = 10*mV # E3 @v/set Z[ 2] = 8*mV # E3
@irena/l1t 13 Z[13] 0x003 # A1H @irena/l1t 13 Z[13] 0x003 # A1H
@irena/l1t 12 Z[12] 0x003 # A1L @irena/l1t 12 Z[12] 0x003 # A1L
@irena/l1t 10 Z[10] 0x003 # A2H @irena/l1t 10 Z[10] 0x003 # A2H
@ -75,9 +75,9 @@
@irena/l1t 8 Z[ 8] 0x041 # E1 @irena/l1t 8 Z[ 8] 0x041 # E1
@irena/l1t 5 Z[ 5] 0x041 # E2 @irena/l1t 5 Z[ 5] 0x041 # E2
@irena/l1t 2 Z[ 2] 0x041 # E3 @irena/l1t 2 Z[ 2] 0x041 # E3
@irena/l2t/ch=0/any=0x001/read=0x3ffff any @irena/l2t/ch=0/disable
@irena/l2t/ch=1/any=0x00a/read=0x3ffff A·C @irena/l2t/ch=1/any=0x00a/read=0x3ffff A·C
@irena/l2t/ch=2/any=0x010/read=0x3ffff D @irena/l2t/ch=2/any=0x010/read=0x3ffff D
@irena/l2t/ch=3/any=0x068/read=0x3ffff C·E0·E @irena/l2t/ch=3/any=0x060/read=0x3ffff E0·E
@irena/l2t/ch=4/any=0x042/read=0x3ffff A·E @irena/l2t/ch=4/any=0x022/read=0x3ffff A·E0
@irena/l2t/ch=5/any=0x100/read=0x3ffff DL @irena/l2t/ch=5/any=0x00e/read=0x3ffff ABC

View file

@ -7,5 +7,5 @@ var H=100
chaos/cmd "H" H chaos/cmd "H" H
chaos/cmd "LE" 20 chaos/cmd "LE" 20
@s/if sd_write_size > 10: var sd_write_size = 10 @s/if sd_write_size > 10: var sd_write_size = 10
@e/info "SAFED p = %d %d", pressure[0], pressure[1]
@script/spy/none @script/spy/none
@e/info "SAFED", pressure[0], pressure[1]

View file

@ -32,6 +32,14 @@ BEGIN {
ph_d = 0 ph_d = 0
sThr = 100 sThr = 100
# HK
HKREF = 3.3/65536
T_ch = 9
T_R1 = 10e3
T_beta = 3758
T_R25 = 10e3
nEa = 60
if (UNIT) @UNIT() if (UNIT) @UNIT()
} }
@ -157,9 +165,17 @@ function CHAOS() {
E3 = 2; thr[E3 ] = 20; ch[17] = E3 ; name[17] = "E3" E3 = 2; thr[E3 ] = 20; ch[17] = E3 ; name[17] = "E3"
CHK = B CHK = B
T_ref = 65536
T_R25 = 10e3 T_R25 = 10e3
T_beta = 3758 T_beta = 3758
# T_R1 = 33e3 # T_R1 = 33e3
T8_R1 = 33e3
T8_beta = T_beta
T8_R25 = T_R25
T12_R1 = T8_R1
T12_beta = T_beta
T12_R25 = T_R25
} }
function isCHAOS() { function isCHAOS() {
@ -812,16 +828,6 @@ END {
} }
} }
BEGIN {
HKREF = 3.3/65536
T_ch = 9
T_R1 = 10e3
T_beta = 3758
T_R25 = 10e3
nEa = 60
}
function isTime() { function isTime() {
if (!/^H /) return 0 if (!/^H /) return 0
Time = $2 Time = $2
@ -875,6 +881,15 @@ function Dtime() {
return Dt return Dt
} }
function degC(d, R1, R25, beta, R,T) {
if (d<1) {
R = R1 * d / (1 - d)
T = beta / (log(R/R25) + beta/298.0) - 273
} else {
T = "×"
}
return T
}
function isHK() { function isHK() {
if (/^E/) { if (/^E/) {
@ -883,7 +898,7 @@ function isHK() {
} }
if (!isTime()) return 0 if (!isTime()) return 0
if (/ 0 0 /) return 0 if (/ 0 0 /) return 0
Ibias = $5*HKREF*100 Ibias = $5*HKREF*97
Vbias = -$11*HKREF*50 + VbiasOffset Vbias = -$11*HKREF*50 + VbiasOffset
Icc = $6*HKREF*100 Icc = $6*HKREF*100
Iss = -$7*HKREF*100 Iss = -$7*HKREF*100
@ -899,12 +914,10 @@ function isHK() {
T = $T_ch/$4 T = $T_ch/$4
} else } else
T = 0 T = 0
if (T<1) { T = degC(T, T_R1, T_R25, T_beta)
T = T_R1 * T/(1-T) if (T8_R1) Ifet = degC($8/0x10000, T8_R1, T8_R25, T8_beta)
T = T_beta / (log(T/T_R25) + T_beta/298.0) - 273 if (T12_R1) Vfet = degC($12/0x10000, T12_R1, T12_R25, T12_beta)
} else {
T = "×"
}
if (!IbiasA) { IbiasA = Ibias } else { if (!IbiasA) { IbiasA = Ibias } else {
IbiasA *= 59/60 IbiasA *= 59/60
IbiasA += Ibias/60 IbiasA += Ibias/60
@ -927,6 +940,10 @@ function do_nE( dt) {
} }
function doHK() { function doHK() {
if (!did_head) {
print "Time, Ibias, Vbias, T, IbiasA, Vprim, Vcc, Vss, Icc, Iss, Vdac, Vfet, Ifet, nErate, nEErate"
did_head=1
}
do_nE() do_nE()
print Time, Ibias, Vbias, T, IbiasA, Vprim, Vcc, Vss, Icc, Iss, Vdac, Vfet, Ifet, nErate, nEErate print Time, Ibias, Vbias, T, IbiasA, Vprim, Vcc, Vss, Icc, Iss, Vdac, Vfet, Ifet, nErate, nEErate
} }

View file

@ -4,6 +4,8 @@ CFLAGS = -O3 -Wall -g -fno-exceptions $(patsubst %,-Wno-%,$(DONTWARN))
LDLIBS = -lm LDLIBS = -lm
default: irenafile default: irenafile
UNIT = CHAOS
irenafile: irenafile:
make -C ../adam make -C ../adam
ln -sf ../adam/irenafile ln -sf ../adam/irenafile
@ -57,7 +59,7 @@ irenafile:
$< >$@ $< >$@
%.HK: %.EI IRENA.awk %.HK: %.EI IRENA.awk
./IRENA.awk 'isHK(){doHK()}' $< >$@ ./IRENA.awk -v UNIT=CHAOS 'isHK(){doHK()}' $< >$@
%.HCHAOS: %.EI IRENA.awk %.HCHAOS: %.EI IRENA.awk
./IRENA.awk -v UNIT=CHAOS 'CHAOSHK(){doCHAOSHK()}' $< >$@ ./IRENA.awk -v UNIT=CHAOS 'CHAOSHK(){doCHAOSHK()}' $< >$@