Commit 1fb0b0c3 authored by springob's avatar springob
Browse files

* BOB3 update


git-svn-id: svn://svn.code.sf.net/p/nibo/code/niborobolib/trunk/arduino16/libraries/BOB3/src@321 2d339c8f-7935-0410-b692-f2b57624aac1
parent 75a835e4
#ifndef _BOB3_H_
#define _BOB3_H_
#if (defined (ARDUINO)) && (!defined (ARDUINO_AVR_BOB3))
#error "BOB3 library should be used with a BOB3 robot as board!"
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <bob3/utils.h>
void setup();
void loop();
enum {
ARM_NONE,
ARM_TOP,
ARM_MID_TOP,
ARM_MID_BOT,
ARM_BOT
};
enum {
OFF = 0x000,
WHITE = 0xfff,
ON = 0xfff,
RED = 0xf00,
GREEN = 0x0f0,
BLUE = 0x00f,
YELLOW = 0xff0,
CYAN = 0x0ff,
FUCHSIA = 0xf0f,
ORANGE = 0xf80,
KABARED = 0xd42,
PURPLE = 0xf08,
VIOLET = 0x63a,
AQUAMARINE = 0x7fd,
BROWN = 0xa33,
CORAL = 0xf75,
CORNFLOWERBLUE = 0x69e,
STEELBLUE = 0x48a,
ROYALBLUE = 0x46e,
FORESTGREEN = 0x282,
SEAGREEN = 0x5f9
};
enum {
ARM_1 = 1,
ARM_2 = 2,
EYE_1 = 1,
EYE_2 = 2,
LED_3 = 3,
LED_4 = 4
};
class Bob3 {
public:
void init();
void setLed(uint8_t id, uint16_t color);
uint16_t getLed(uint8_t id);
void setEyes(uint16_t eye1, uint16_t eye2) {setLed(1, eye1); setLed(2, eye2);};
void setWhiteLeds(uint16_t wled1, uint16_t wled2) {setLed(3, wled1); setLed(4, wled2);};
uint16_t getIRSensor();
uint16_t getIRLight();
void enableIRSensor(bool enable);
uint8_t getArm(uint8_t id);
void enableArms(bool enable);
uint16_t getTemperature();
uint16_t getMillivolt();
uint8_t getID();
int16_t receiveIRCode(uint8_t carrier, uint16_t timeout);
void transmitIRCode(uint8_t carrier, uint8_t code);
int16_t receiveIRCode(uint16_t timeout) {return receiveIRCode(0, timeout);}
void transmitIRCode(uint8_t code) {transmitIRCode(0, code);}
};
extern Bob3 bob3;
#if !defined(ARDUINO)
inline static
void delay(uint16_t ms) {while (ms--) _delay_ms(1);}
#endif
inline static uint16_t rgb(uint8_t r, uint8_t g, uint8_t b) __attribute__((const));
inline static
uint16_t rgb(uint8_t r, uint8_t g, uint8_t b) {return ((uint16_t)r<<8)|(g<<4)|b;}
uint16_t mixColor(uint16_t color1, uint16_t color2, uint8_t w1, uint8_t w2);
uint16_t hsv(int16_t h, uint8_t s, uint8_t v);
uint16_t hsvx(uint8_t h, uint8_t s, uint8_t v);
uint16_t randomNumber(uint16_t lo, uint16_t hi);
uint16_t randomBits(uint8_t zeros, uint8_t ones);
uint32_t random32();
static inline
uint8_t random8() {
return random32() & 0xff;
}
static inline
uint16_t random16() {
return random32() & 0xffff;
}
#endif
#include <bob3/bob3.h>
......@@ -49,15 +49,21 @@ extern "C" {
#endif
extern uint8_t _bob3_revision;
extern uint8_t _arm_mode;
uint16_t analog_samples[2 * ANALOG_CNT];
uint16_t analog_random_seed;
uint8_t analog_pos;
uint8_t analog_flags;
//uint8_t analog_pos;
//uint8_t analog_flags;
volatile uint8_t analog_sample_id;
uint16_t analog_sum;
// Interrupt
uint8_t analog_ui_ch;
uint8_t analog_ui_cnt;
uint8_t analog_first = 1;
#define AREF_1V1(x) (_BV(REFS1)|_BV(REFS0)|((x)))
#define AREF_AVCC(x) (_BV(REFS0)|((x)))
#define AREF_EXT(x) ((x))
......@@ -66,6 +72,8 @@ uint16_t analog_sum;
#define AMUX_0V 0x0f
void analog_init() {
analog_first = 1;
analog_ui_ch = 3;
#if defined(DIDR0)
// DIDR0 = 0xff;
#endif
......@@ -268,22 +276,80 @@ void _key_update_event() {
#endif
#define CASE_ADC(CASE, ANALOG_CH, IO_EN_BIT, AREF, APORT) \
case CASE+STD0: \
ADMUX = AREF(APORT); \
PORTC &= ~_BV(APORT);\
DDRC |= _BV(APORT);\
DDRC &= ~_BV(APORT);\
PORTC |= _BV(APORT);\
break; \
case CASE+STD2: \
analog_samples[ANALOG_CH]=value; \
set_output_bit(IO_EN_BIT); \
break; \
case CASE+STD5: \
analog_samples[ANALOG_CH+ANALOG_CNT]=value; \
clear_output_bit(IO_EN_BIT); \
break;
// **** IR Sensor ****
static inline void analog_ai_ir(uint16_t value) {
if (analog_ui_cnt==0) {
ADMUX = AREF_1V1(IOG_ANALOG_BIT_SENS_IR);
} else if (analog_ui_cnt==6) {
ADMUX = AREF_1V1(IOG_ANALOG_BIT_SENS_IR);
PORTC &= ~_BV(IOG_ANALOG_BIT_SENS_IR);
DDRC |= _BV(IOG_ANALOG_BIT_SENS_IR);
DDRC &= ~_BV(IOG_ANALOG_BIT_SENS_IR);
PORTC |= _BV(IOG_ANALOG_BIT_SENS_IR);
} else if (analog_ui_cnt==8) {
analog_sum = value;
} else if (analog_ui_cnt==9) {
analog_sum += value;
} else if (analog_ui_cnt==10) {
analog_sum += value;
} else if (analog_ui_cnt==11) {
analog_sum += value;
analog_samples[ANALOG_IR] = analog_sum/4;
activate_output_bit(IO_EN_IR);
set_output_bit(IO_EN_IR);
} else if (analog_ui_cnt==14) {
analog_sum = value;
} else if (analog_ui_cnt==15) {
analog_sum += value;
} else if (analog_ui_cnt==16) {
analog_sum += value;
} else if (analog_ui_cnt==17) {
analog_sum += value;
analog_samples[ANALOG_IR+ANALOG_CNT] = analog_sum/4;
clear_output_bit(IO_EN_IR);
analog_ui_cnt = 0;
return;
}
analog_ui_cnt++;
}
// **** Temperature Sensor ****
static inline void analog_ai_temp(uint16_t value) {
if (analog_ui_cnt==0) {
ADMUX = AREF_1V1(AMUX_TEMP);
} else if (analog_ui_cnt==4) {
analog_sum = value;
} else if (analog_ui_cnt==5) {
analog_sum += value;
} else if (analog_ui_cnt==6) {
analog_sum += value;
} else if (analog_ui_cnt==7) {
analog_sum += value;
value = analog_sum;
analog_samples[ANALOG_TEMP] = value;
value += 7*analog_samples[ANALOG_CNT+ANALOG_TEMP] + 4;
value /= 8;
analog_samples[ANALOG_CNT+ANALOG_TEMP] = value;
analog_ui_cnt = 0;
return;
}
analog_ui_cnt++;
}
// **** Supply Voltage Sensor ****
static inline void analog_ai_volt(uint16_t value) {
if (analog_ui_cnt==0) {
ADMUX = AREF_AVCC(AMUX_1V1);
} else if (analog_ui_cnt==2) {
analog_samples[ANALOG_VOLT] = value;
analog_ui_cnt = 0;
return;
}
analog_ui_cnt++;
}
#define CASE_ADC_KEY(CASE, ANALOG_CH, IO_EN_BIT, AREF, APORT) \
......@@ -305,119 +371,149 @@ void _key_update_event() {
analog_samples[ANALOG_CH]=updateKey(analog_samples[ANALOG_CH], analog_sum/4); \
break;
#define CASE_ADC2(CASE, ANALOG_CH, IO_EN_BIT, AREF, APORT) \
case CASE+STD0: \
ADMUX = AREF(APORT); \
PORTC &= ~_BV(APORT);\
DDRC |= _BV(APORT);\
DDRC &= ~_BV(APORT);\
PORTC |= _BV(APORT);\
break; \
case CASE+STD2: \
analog_sum = value; \
break; \
case CASE+STD2+1: \
analog_sum += value; \
break; \
case CASE+STD2+2: \
analog_sum += value; \
break; \
case CASE+STD2+3: \
analog_sum += value; \
analog_samples[ANALOG_CH] = analog_sum/4; \
activate_output_bit(IO_EN_BIT); \
set_output_bit(IO_EN_BIT); \
break; \
case CASE+STD2+STD3+3: \
analog_sum = value; \
break; \
case CASE+STD2+STD3+4: \
analog_sum += value; \
break; \
case CASE+STD2+STD3+5: \
analog_sum += value; \
break; \
case CASE+STD2+STD3+6: \
analog_sum += value; \
analog_samples[ANALOG_CH+ANALOG_CNT] = analog_sum/4; \
clear_output_bit(IO_EN_BIT); \
break;
// **** Supply Voltage Sensor ****
static inline void analog_ai_key_v102(uint16_t value) {
switch (analog_ui_cnt) {
CASE_ADC_KEY(0*STD6, ANALOG_L0, IO_ARM_1R, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(1*STD6, ANALOG_L1, IO_ARM_1C, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(2*STD6, ANALOG_L2, IO_ARM_1C, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(3*STD6, ANALOG_L3, IO_ARM_1R, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(4*STD6, ANALOG_R0, IO_ARM_2R, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(5*STD6, ANALOG_R1, IO_ARM_2C, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(6*STD6, ANALOG_R2, IO_ARM_2C, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(7*STD6, ANALOG_R3, IO_ARM_2R, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
}
analog_ui_cnt++;
if (analog_ui_cnt >= 8*STD6) {
analog_ui_cnt = 0;
}
}
// **** Supply Voltage Sensor ****
static inline void analog_ai_key_v103(uint16_t value) {
switch (analog_ui_cnt) {
CASE_ADC_KEY(0*STD6, ANALOG_L0, IO_ARM2_TA, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(1*STD6, ANALOG_L1, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(2*STD6, ANALOG_L2, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(3*STD6, ANALOG_L3, IO_ARM2_TC, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(4*STD6, ANALOG_R0, IO_ARM2_TA, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(5*STD6, ANALOG_R1, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(6*STD6, ANALOG_R2, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(7*STD6, ANALOG_R3, IO_ARM2_TC, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
}
analog_ui_cnt++;
if (analog_ui_cnt >= 8*STD6) {
analog_ui_cnt = 0;
}
}
// **** Supply Voltage Sensor ****
static inline void analog_ai_key_detect(uint16_t value) {
switch (analog_ui_cnt) {
case 0:
// set all arm output pins to vcc level
set_output_bit(IO_ARM2_TA);
set_output_bit(IO_ARM2_TB);
set_output_bit(IO_ARM2_TC);
activate_output_bit(IO_ARM2_TA);
activate_output_bit(IO_ARM2_TB);
activate_output_bit(IO_ARM2_TC);
// enable pull-ups on arm input pins
deactivate_output_bit(IO_ARM2_S1);
deactivate_output_bit(IO_ARM2_S2);
set_output_bit(IO_ARM2_S1);
set_output_bit(IO_ARM2_S2);
ADMUX = AREF_AVCC(IOG_ANALOG_BIT_ARM2_S1);
break;
case 2*STD6:
analog_sum = value;
break;
case 2*STD6+1:
analog_sum += value;
break;
case 2*STD6+2:
analog_sum += value;
break;
case 2*STD6+3:
analog_sum += value;
break;
case 2*STD6+4:
analog_sum /= 2;
analog_sum += 15*analog_samples[ANALOG_L0]+7;
analog_sum /= 16;
break;
case 2*STD6+5:
analog_samples[ANALOG_L0] = analog_sum;
ADMUX = AREF_AVCC(IOG_ANALOG_BIT_ARM2_S2);
break;
case 4*STD6:
analog_sum = value;
break;
case 4*STD6+1:
analog_sum += value;
break;
case 4*STD6+2:
analog_sum += value;
break;
case 4*STD6+3:
analog_sum += value;
break;
case 4*STD6+4:
analog_sum /= 2;
analog_sum += 15*analog_samples[ANALOG_R0]+7;
analog_sum /= 16;
break;
case 4*STD6+5:
analog_samples[ANALOG_R0] = analog_sum;
break;
}
analog_ui_cnt++;
if (analog_ui_cnt >= 8*STD6) {
analog_ui_cnt = 0;
}
}
ISR(ADC_vect) {
uint16_t value = ADC;
sei();
switch (analog_ui_ch) {
// Vcc Voltage Ref
case 0: analog_ai_key_v102(value); break;
case 1: analog_ai_key_v103(value); break;
case 2: analog_ai_key_detect(value); break;
// 1.1V Voltage Ref
case 3: analog_ai_ir(value); break;
case 4: analog_ai_temp(value); break;
// Vcc Voltage Ref
case 5: analog_ai_volt(value); break;
}
if (_bob3_revision==102) {
// BOB3 V1.2
switch (analog_pos) {
CASE_ADC_KEY(0*STD6, ANALOG_L0, IO_ARM_1R, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(1*STD6, ANALOG_L1, IO_ARM_1C, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(2*STD6, ANALOG_L2, IO_ARM_1C, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(3*STD6, ANALOG_L3, IO_ARM_1R, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(4*STD6, ANALOG_R0, IO_ARM_2R, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(5*STD6, ANALOG_R1, IO_ARM_2C, AREF_AVCC, IOG_ANALOG_BIT_ARM_U)
CASE_ADC_KEY(6*STD6, ANALOG_R2, IO_ARM_2C, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
CASE_ADC_KEY(7*STD6, ANALOG_R3, IO_ARM_2R, AREF_AVCC, IOG_ANALOG_BIT_ARM_L)
case 8*STD6:
ADMUX = AREF_1V1(IOG_ANALOG_BIT_SENS_IR);
break;
CASE_ADC2(9*STD6, ANALOG_IR, IO_EN_IR, AREF_1V1, IOG_ANALOG_BIT_SENS_IR)
case 11*STD6:
ADMUX = AREF_1V1(AMUX_TEMP);
break;
case 11*STD6+STD4:
analog_sum = value;
break;
case 11*STD6+STD4+1:
analog_samples[ANALOG_TEMP] = (analog_sum+value)>>1;
break;
case 12*STD6:
ADMUX = AREF_AVCC(AMUX_1V1);
break;
case 12*STD6+STD2: {
analog_samples[ANALOG_VOLT] = value;
} break;
if (analog_ui_cnt==0) {
if (analog_ui_ch<3) analog_ui_ch=3;
else if (analog_ui_ch<5) analog_ui_ch++;
else if (_bob3_revision==102) analog_ui_ch=0;
else if (_arm_mode==1) analog_ui_ch=1;
else if (_arm_mode==2) analog_ui_ch=2;
else analog_ui_ch=0;
if (analog_ui_ch<3) {
analog_irq_hook();
analog_sample_id++;
analog_random_seed<<=1;
if (analog_first) {
analog_first = 0;
analog_samples[ANALOG_TEMP+ANALOG_CNT] = analog_samples[ANALOG_TEMP];
}
}
} else if (_bob3_revision==103) {
// BOB3 V1.3
switch (analog_pos) {
CASE_ADC_KEY(0*STD6, ANALOG_L0, IO_ARM2_TA, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(1*STD6, ANALOG_L1, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(2*STD6, ANALOG_L2, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(3*STD6, ANALOG_L3, IO_ARM2_TC, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S1)
CASE_ADC_KEY(4*STD6, ANALOG_R0, IO_ARM2_TA, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(5*STD6, ANALOG_R1, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(6*STD6, ANALOG_R2, IO_ARM2_TB, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
CASE_ADC_KEY(7*STD6, ANALOG_R3, IO_ARM2_TC, AREF_AVCC, IOG_ANALOG_BIT_ARM2_S2)
case 8*STD6:
ADMUX = AREF_1V1(IOG_ANALOG_BIT_SENS_IR);
break;
CASE_ADC2(9*STD6, ANALOG_IR, IO_EN_IR, AREF_1V1, IOG_ANALOG_BIT_SENS_IR)
case 11*STD6:
ADMUX = AREF_1V1(AMUX_TEMP);
break;
case 11*STD6+STD4:
analog_sum = value;
break;
case 11*STD6+STD4+1:
analog_samples[ANALOG_TEMP] = (analog_sum+value)>>1;
break;
case 12*STD6:
ADMUX = AREF_AVCC(AMUX_1V1);
break;
case 12*STD6+STD2: {
analog_samples[ANALOG_VOLT] = value;
} break;
}
}
if (++analog_pos>(12*STD6+STD2)) {
analog_pos=0;
analog_irq_hook();
analog_sample_id++;
analog_random_seed<<=1;
}
analog_random_seed += value;
ADCSRA |= _BV(ADSC);
}
......
......@@ -6,7 +6,6 @@
#include "iodefs.h"
#include "ircom.h"
#ifdef __cplusplus
extern "C" {
#endif
......@@ -19,26 +18,16 @@ extern "C" {
#define AMUX_TEMP 0x08
#define AMUX_1V1 0x0e
#define AMUX_0V 0x0f
#if defined(ARDUINO)
void _time_suspend();
void _time_resume();
#else
inline static void _time_suspend() {}
inline static void _time_resume() {}
#endif
static void start_timer(uint8_t carrier) {
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS11); // CTC[OCR1A], PS=8
TCCR1B = _BV(WGM12) | _BV(CS11); // CTC, PS=8
OCR1A = 250-1; // 250 us
}
static void stop_timer() {
TCCR1B = 0;
_time_resume();
TCCR1B = 0;
}
static void wait_timer() {
......
#if !defined(ARDUINO)
#include "bob3.h"
#include <avr/io.h>
#include <avr/interrupt.h>
......@@ -28,17 +26,3 @@ int main () {
loop();
}
}
#else
#include "BOB3.h"
extern "C" void _time_resume();
extern "C" void bob3_init() {
bob3.init();
_time_resume();
}
#endif
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