Compare commits
10 commits
d8b37d1f92
...
46e0ebda74
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46e0ebda74 | ||
|
|
86b3b52126 | ||
|
|
bf9f238b0c | ||
|
|
50263b9cc2 | ||
|
|
d06e324d55 | ||
|
|
19192ec206 | ||
|
|
6ebc588ecd | ||
|
|
af21d0066e | ||
|
|
d392a69c06 | ||
|
|
e064002e15 |
52 changed files with 63 additions and 6950 deletions
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
@ -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_
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
@ -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_
|
|
||||||
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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++);
|
|
||||||
}
|
|
||||||
91
avr/Makefile
91
avr/Makefile
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)).
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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_ */
|
|
||||||
|
|
@ -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})
|
|
||||||
|
|
||||||
117
avr/spislave.c
117
avr/spislave.c
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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]
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()}' $< >$@
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue