Commit 114a55bb authored by Anders Blomdell's avatar Anders Blomdell
Browse files

First version of program for ball_and_beam-2018

parent 35570f3d
TARGETS=ball_and_beam-2018
ball_and_beam-2018.ARCH=avr
ball_and_beam-2018.CHIP=atmega32
# 14.7456 MHz crystal, brown out
ball_and_beam-2018.FUSE_L=0x1f
ball_and_beam-2018.FUSE_H=0xd9
ball_and_beam-2018.C=ball_and_beam-2018
include ../../lib/avr/Makefile.common
#include <avr/eeprom.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include "serialio.h"
/*
* Serial I/O assignments:
*
* DI 0 -- Motor Overtemp
*
* DO 0 -- Motor Brake
* DO 1 -- Accelerometer Self-Test
*
* AI 0 -- Ball Position
* AI 1 -- Motor Current
* AI 2 -- Accelerometer X
* AI 3 -- Accelerometer Y
* AI 4 -- Accelerometer Z
* EI 5 -- Motor Position
*
* AO 0 -- Motor Speed
*/
/*
* Used I/O pins
*
* PA0 Ball Position
* PA1 Motor Current
* PA2 Accelerometer X
* PA3 Accelerometer Y
* PA4 Accelerometer Z
*
* PB0 Ball On Beam
* PB1 Motor direction
* PB2 Encoder Z
* PB3 Motor Brake
* PB4 Motor Thermal Flag
* PB5 Programming MOSI
* PB6 Programming MISO
* PB7 Programming SCK
*
* PD0 Serial In
* PD1 Serial Out
* PD2 Encoder A
* PD3 Encoder B
* PD5 Motor PWM
*/
volatile unsigned char error;
volatile uint8_t serial_readbits;
volatile uint8_t serial_readchannels;
volatile uint8_t serial_readconfig;
struct values {
/* Outputs */
uint8_t motorBrake;
uint16_t motorSpeed;
uint8_t accelerometerSelfTest;
/* Inputs */
int16_t ballPosition;
int16_t motorCurrent;
int16_t accelerometerX;
int16_t accelerometerY;
int16_t accelerometerZ;
int32_t motorEncoder;
int8_t motorThermalFlag;
int8_t ballOnBeam;
uint8_t timer;
};
volatile struct values global;
SIGNAL(ADC_vect)
{
unsigned char channel = ADMUX & 0x0f;
unsigned int value = ADCW;
if (global.timer) {
global.timer--;
PORTD &= ~0x40;
} else {
PORTD |= 0x40;
}
switch (channel) {
case 0: {
channel = 1;
global.ballPosition = value;
} break;
case 1: {
channel = 2;
global.motorCurrent = value;
} break;
case 2: {
channel = 3;
global.accelerometerX = value;
} break;
case 3: {
channel = 4;
global.accelerometerY = value;
} break;
case 4: {
channel = 5;
global.accelerometerZ = value;
} break;
default: {
channel = 0;
} break;
}
ADMUX = 0x00 | channel; // Vref = external, right adjust
ADCSRA = 0xcf; // Enable ADC interrupts, Clock/128
}
typedef enum { cmd_clear_bit, cmd_set_bit,
cmd_read_bit, cmd_read_chan } command;
SIGNAL(USART_RXC_vect)
{
char ch = UDR;
global.timer = 0xff;
switch (serialio_RXC(ch)) {
case serialio_clearbit: {
switch (serialio_channel) {
case 0: { PORTB &= ~0x08; } break;
case 1: { PORTC &= ~0x80; } break;
}
} break;
case serialio_setbit: {
switch (serialio_channel) {
case 0: { PORTB |= 0x08; } break;
case 1: { PORTC |= 0x80; } break;
}
} break;
case serialio_pollbit: {
if (serialio_channel < 1) {
serial_readbits |= (1<<serialio_channel);
}
} break;
case serialio_pollchannel: {
if (serialio_channel < 6) {
serial_readchannels |= (1<<serialio_channel);
} else if (serialio_channel == 31) {
serial_readconfig = 1;
}
} break;
case serialio_setchannel: {
switch (serialio_channel) {
case 0: {
int16_t speed;
if (serialio_value < 0x400) {
speed = 0x400 - serialio_value;
PORTB |= 0x02;
} else {
speed = serialio_value - 0x400;
PORTB &= ~0x02;
}
OCR1A = speed & 0x3ff;
} break;
} break;
} break;
case serialio_error: {
} break;
case serialio_more: {
} break;
}
}
int main()
{
serialio_init();
serial_readbits = 0;
serial_readchannels = 0;
serial_readconfig = 0;
PORTA = 0x00; // PortA, pull-ups
DDRA = 0x00; // PortA, all inputs
PORTB = 0x00; // PortB, pull-ups / initial values
DDRB = 0x0a; // PortB, bits 1 & 3 outputs
PORTC = 0x00; // PortC, pull-ups / initial values
DDRC = 0x80; // PortC, bit 7 output
PORTD = 0x00; // PortD, pull-ups / initial values
DDRD = 0x20; // PortD, bit 5 output
TCCR0 = 0x05; // Timer0, Clock / 1024
TCCR1A = 0x83; // OC1A 10 bit PWM (Phase Correct), clear A on match
TCCR1B = 0x01; // Clock / 1
OCR1A = 0 & 0x3ff;
UCSRA = 0x00; // USART:
UCSRB = 0x98; // USART: RxIntEnable|RxEnable|TxEnable
UCSRC = 0x86; // USART: 8bit, no parity
UBRRH = 0; // USART: 115200 @ 14.7456MHz
UBRRL = 7; // USART: 115200 @ 14.7456MHz
ADMUX = 0x00; // Vref = external, right adjust
ADMUX = 0x0e; // Vref = external, right adjust, read 1.22V (Vbg)
ADCSRA = 0xcf; // Enable ADC interrupts, Clock/128
SREG = 0x80; // Global interrupt enable
while (1) {
unsigned char bits, channels, config;
struct values local;
SREG = 0x00; // Global interrupt disable
bits = serial_readbits;
serial_readbits = 0;
channels = serial_readchannels;
serial_readchannels = 0;
config = serial_readconfig;
serial_readconfig = 0;
local = global;
SREG = 0x80; // Global interrupt enable
if (channels & 0x01) { serialio_putchannel(0, local.ballPosition); }
if (channels & 0x02) { serialio_putchannel(1, local.motorCurrent); }
if (channels & 0x04) { serialio_putchannel(2, local.accelerometerX); }
if (channels & 0x08) { serialio_putchannel(3, local.accelerometerY); }
if (channels & 0x10) { serialio_putchannel(4, local.accelerometerZ); }
if (channels & 0x20) { serialio_putchannel(5, local.motorEncoder); }
if (bits & 0x01) { serialio_putbit(0, PORTB & 0x10); } // thermalFlag
if (config) {
CONF_DIGITAL_IN(0, CONF_RESOLUTION(1)); // motorTemp
CONF_DIGITAL_OUT(0, CONF_RESOLUTION(1)); // motorBrake
CONF_DIGITAL_OUT(1, CONF_RESOLUTION(1)); // accelerometerSelfTest
CONF_ANALOG_IN(0, CONF_RESOLUTION(10)); // ballPosition
CONF_ANALOG_IN(0, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(0, CONF_MAX(CONF_POSITIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(1, CONF_RESOLUTION(10)); // motorCurrent
CONF_ANALOG_IN(1, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(1, CONF_MAX(CONF_POSITIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(2, CONF_RESOLUTION(10)); // accelerometerX
CONF_ANALOG_IN(2, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(2, CONF_MAX(CONF_POSITIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(3, CONF_RESOLUTION(10)); // accelerometerY
CONF_ANALOG_IN(3, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(3, CONF_MAX(CONF_POSITIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(4, CONF_RESOLUTION(10)); // accelerometerZ
CONF_ANALOG_IN(4, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(10000)));
CONF_ANALOG_IN(4, CONF_MAX(CONF_POSITIVE_MILLIVOLT(10000)));
CONF_ENCODER_IN(5, CONF_RESOLUTION(32)); // motorPosition
CONF_ANALOG_OUT(0, CONF_RESOLUTION(11)); // motorSpeed
CONF_ANALOG_OUT(0, CONF_MIN(CONF_NEGATIVE_MILLIVOLT(12000)));
CONF_ANALOG_OUT(0, CONF_MAX(CONF_POSITIVE_MILLIVOLT(12000)));
CONF_END();
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment