]> jspc29.x-matter.uni-frankfurt.de Git - avr.git/commitdiff
framework for pt100 reader
authorJan Michel <j.michel@gsi.de>
Tue, 4 Aug 2015 16:57:10 +0000 (18:57 +0200)
committerJan Michel <j.michel@gsi.de>
Tue, 4 Aug 2015 16:57:10 +0000 (18:57 +0200)
pt100/Makefile
pt100/eeprom.c [new file with mode: 0644]
pt100/keys.c [new file with mode: 0644]
pt100/lcdlib/lcd-color-graphic.c
pt100/lcdlib/lcd-color-graphic.h
pt100/main.c
pt100/main.h
pt100/tempmeas.c [new file with mode: 0644]
pt100/uart.c [new file with mode: 0644]

index 61201f887d4061b3f54d3c2e216ce59a6b2a676b..73d8224e8c83a4db2a18e9ee3e387357687834bf 100644 (file)
@@ -5,12 +5,13 @@
 # (GNU make, BSD make, SysV make)
 
 
-MCU = atmega1284p
+MCU = atmega324p
 FORMAT = ihex
 TARGET = main
 SRC = $(TARGET).c lcdlib/lcd-color-graphic.c lcdlib/font.c \
       lcdlib/Fonts/digits_24px.c lcdlib/Fonts/digits_32px.c lcdlib/Fonts/font_proportional_16px.c \
-      lcdlib/Fonts/font_proportional_8px.c lcdlib/Fonts/symbols_16px.c
+      lcdlib/Fonts/font_proportional_8px.c lcdlib/Fonts/symbols_16px.c \
+      uart.c eeprom.c tempmeas.c keys.c
 ASRC = 
 OPT = 2
 
@@ -114,7 +115,7 @@ AVRDUDE_FLAGS = $(AVRDUDE_BASIC) $(AVRDUDE_NO_VERIFY) $(AVRDUDE_VERBOSE) $(AVRDU
 CC = avr-gcc
 OBJCOPY = avr-objcopy
 OBJDUMP = avr-objdump
-SIZE = avr-size
+SIZE = ~/bin/avr-size
 NM = avr-nm
 AVRDUDE = avrdude
 REMOVE = rm -f
@@ -135,7 +136,7 @@ ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
 # Default target.
 all: build
 
-build: elf hex eep lss
+build: elf hex eep lss size
 
 elf: $(TARGET).elf
 hex: $(TARGET).hex
@@ -150,7 +151,7 @@ program: $(TARGET).hex $(TARGET).eep
 
 
 size: 
-       $(SIZE)  $(TARGET).elf
+       $(SIZE) -C --mcu=$(MCU)  $(TARGET).elf
 #-C --mcu=$(MCU)  
 # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
 COFFCONVERT=$(OBJCOPY) --debugging \
diff --git a/pt100/eeprom.c b/pt100/eeprom.c
new file mode 100644 (file)
index 0000000..9ae56e5
--- /dev/null
@@ -0,0 +1,10 @@
+#include <avr/eeprom.h>
+
+
+void eeprom_write(uint8_t addr, uint16_t value) {
+  eeprom_update_word((uint16_t*)(uint16_t)(addr*2),value);
+  }
+  
+uint16_t eeprom_read(uint8_t addr) {
+  return eeprom_read_word((uint16_t*)(uint16_t)(addr*2));
+  }  
diff --git a/pt100/keys.c b/pt100/keys.c
new file mode 100644 (file)
index 0000000..3d49b5b
--- /dev/null
@@ -0,0 +1,22 @@
+#include "main.h"
+
+
+void scan_keys(void){
+  static uint8_t key_state_m0, key_state_m1;
+  uint8_t key_state = ~(KEYPIN) & ACTIVE_KEYS_MASK;
+  //              -------has state changed?----   --- is key pressed now? ---
+  keys_pressed |= (key_state_m0 ^ key_state_m1) &         key_state;
+  
+  key_state_m1 = key_state_m0;
+  key_state_m0 = key_state;
+}
+
+
+
+uint8_t key_was_pressed(uint8_t key_mask){
+  // was one of the keys defined by key mask pressed?
+  uint8_t result = keys_pressed & key_mask;
+  keys_pressed &= ~(key_mask);
+  return result;
+}
+  
\ No newline at end of file
index 8403f9634afa483853bd868e6a27ffc8dfa5e5d4..a3b1c52d6ee447230a080f77f32f84d505ea5056 100644 (file)
@@ -14,8 +14,8 @@
   * Background is used as background, e.g. when writing fonts.
   */
 
-color_t foreground = {.red=0x1F, .green=0x3F, .blue=0x1F};
-color_t background = {.red=0,    .green=0,    .blue=0};
+color_t foreground;
+color_t background;
 
 
 /******************************************************************************
@@ -25,6 +25,7 @@ void lcd_init() {
   LCD_SET_PIN_DIRECTIONS();  //set outputs
   _delay_ms(1);
   LCD_INIT_SPI();            //Initialize SPI Interface  
+  LCD_UNSELECT();
   _delay_ms(50);
   LCD_RESET_ON();            //Apply Reset to the Display Controller  
   _delay_ms(100); 
@@ -33,6 +34,7 @@ void lcd_init() {
   LCD_SELECT();               //Switches chip select on
   lcd_command(LCD_SLEEP_OUT); //Wake up LCD
   _delay_ms(70);
+  lcd_command_1(LCD_COLOR_MODE,LCD_16BIT);
   return;
   }
 
@@ -40,11 +42,22 @@ void lcd_init() {
 /******************************************************************************
   * Sends a command to the display
   */
-inline void lcd_command(uint8_t c) {
-  spi_wait_for_idle();
-  LCD_CMD();
-  spi_write(c);
-  }
+// inline void lcd_command(uint8_t c) {
+//   spi_wait_for_idle();
+//   LCD_CMD();
+//   spi_write(c);
+//   }
+
+  
+/******************************************************************************
+  * Sends a data word to the display
+  */
+// inline void lcd_data(uint8_t c) {
+//   spi_wait_for_idle();
+//   LCD_DATA();
+//   spi_write(c);
+// }  
+
 
 /******************************************************************************
   * Sends a command with one argument
@@ -53,25 +66,18 @@ inline void lcd_command_1(uint8_t c, uint8_t data) {
   lcd_command(c);
   lcd_data(data);
 }  
-  
-/******************************************************************************
-  * Sends a data word to the display
-  */
-inline void lcd_data(uint8_t c) {
-  spi_wait_for_idle();
-  LCD_DATA();
-  spi_write(c);
-}  
-
-
 
 /******************************************************************************
   * Stores the main drawing color for later use
   */
 inline void lcd_set_foreground(uint8_t r, uint8_t g, uint8_t b) {
-  foreground.red = r;
-  foreground.green = g;
-  foreground.blue = b;
+  uint16_t t = r<<11 | g<<5 | b;
+  foreground.c1 = t>>8;
+  foreground.c2 = t;
+  }
+inline void lcd_use_foreground(color_t color) {
+  foreground.c1 = color.c1;
+  foreground.c2 = color.c2;
   }
 
 
@@ -79,11 +85,24 @@ inline void lcd_set_foreground(uint8_t r, uint8_t g, uint8_t b) {
   * Stores the background color for later use
   */
 inline void lcd_set_background(uint8_t r, uint8_t g, uint8_t b) {
-  background.red = r;
-  background.green = g;
-  background.blue = b;
+  uint16_t t = r<<11 | g<<5 | b;
+  background.c1 = t>>8;
+  background.c2 = t;
   }
-
+inline void lcd_use_background(color_t color) {
+  background.c1 = color.c1;
+  background.c2 = color.c2;
+  }
+  
+/******************************************************************************
+  * Stores the background color for later use
+  */
+inline void lcd_set_color(color_t* color, uint8_t r, uint8_t g, uint8_t b) {
+  uint16_t t = r<<11 | g<<5 | b;
+  color->c1 = t>>8;
+  color->c2 = t;
+  }  
+  
 
 /******************************************************************************
   * Sets the column range used for the next write operation
@@ -91,28 +110,38 @@ inline void lcd_set_background(uint8_t r, uint8_t g, uint8_t b) {
 inline void lcd_set_column(uint16_t start, uint16_t end) {
   lcd_command(LCD_SET_COLUMN);
   lcd_data(start >> 8);
-  lcd_data(start);
-  lcd_data(end >> 8);
-  lcd_data(end);
+  lcd_data_cont(start);
+  lcd_data_cont(end >> 8);
+  lcd_data_cont(end);
   }
-
+inline void lcd_set_column_short(uint16_t start) {
+  lcd_command(LCD_SET_COLUMN);
+  lcd_data(start >> 8);
+  lcd_data_cont(start);
+  }
+  
 /******************************************************************************
   * Sets the page range used for the next write operation
   */
 inline void lcd_set_page(uint16_t start, uint16_t end) {
   lcd_command(LCD_SET_PAGE);
   lcd_data(start >> 8);
-  lcd_data(start);
-  lcd_data(end >> 8);
-  lcd_data(end);
+  lcd_data_cont(start);
+  lcd_data_cont(end >> 8);
+  lcd_data_cont(end);
+  }
+inline void lcd_set_page_short(uint16_t start) {
+  lcd_command(LCD_SET_PAGE);
+  lcd_data(start >> 8);
+  lcd_data_cont(start);
   }
 
 /******************************************************************************
   * Writes a pixel to the display using 16 Bit color mode
   */
 inline void lcd_send_pixel(color_t c) {
-  lcd_data((c.red<<3) | (c.green>>3));
-  lcd_data((c.green<<5) | c.blue);
+  lcd_data(c.c1);
+  lcd_data_cont(c.c2);
   }  
   
 /******************************************************************************
@@ -125,7 +154,16 @@ inline void lcd_set_pixel_xy(uint16_t column, uint16_t page) {
   lcd_send_pixel(foreground);
   }    
 
-
+/******************************************************************************
+  * Sets a pixel at a given position
+  */
+inline void lcd_set_pixel_col_xy(uint16_t column, uint16_t page, color_t col) {
+  lcd_set_page_short(page);
+  lcd_set_column_short(column);
+  lcd_command(LCD_WRITE_MEM);
+  lcd_send_pixel(col);
+  }   
+  
 /******************************************************************************
  * This function sets an area of the screen to a given color
  * col0          - left edge of the area
@@ -162,7 +200,7 @@ uint16_t lcd_current_column = 0;
 uint16_t lcd_inc_page(int16_t s) {
   uint16_t p = lcd_current_page;
   p += s;
-  if (p > LCD_HEIGHT/8)
+  if (p > LCD_HEIGHT)
     p = 0;
   lcd_current_page = p;
   
@@ -197,18 +235,22 @@ void lcd_moveto_xy(uint16_t page, uint16_t column) {
  * Moves the cursor relative to the current position
  * pages         - number of pages to move
  * columns       - number of columns to move
+ * for use with the font library only
  */  
 void lcd_move_xy(int16_t pages, int16_t columns) {
-  lcd_moveto_xy(lcd_inc_page(pages),lcd_inc_column(columns));
+  lcd_moveto_xy(lcd_inc_page(pages*8),lcd_inc_column(columns));
   }
 
 
 /******************************************************************************
  * Takes a vertical byte from the font generator and prints it on the display
  * b             - Bit pattern to display
+ * c             - continue writing in same page
  */ 
-void lcd_write_font_byte(uint8_t b) {
-  lcd_set_page(8*lcd_current_page,8*lcd_current_page+8);
+void lcd_write_font_byte(uint8_t b, uint8_t c) {
+  if(!c) {
+    lcd_set_page(lcd_current_page,lcd_current_page+8);
+    }
   lcd_set_column(lcd_current_column,lcd_current_column);
   lcd_command(LCD_WRITE_MEM);
   for(uint8_t i=0;i<8;i++) {
@@ -220,4 +262,25 @@ void lcd_write_font_byte(uint8_t b) {
     }
   lcd_inc_column(1);
   }
+
+  
+/******************************************************************************
+ * Draws a line according to Bresenham (from wikipedia)
+ */   
+void lcd_draw_line(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1) {
+  int16_t dx =  abs(x1-x0);
+  int16_t sx = x0<x1 ? 1 : -1;
+  int16_t dy = -abs(y1-y0);
+  int16_t sy = y0<y1 ? 1 : -1;
+  int16_t err = dx+dy, e2; /* error value e_xy */
+  for(;;){  /* loop */
+    lcd_set_pixel_xy(x0,y0);
+    if (x0==x1 && y0==y1) break;
+    e2 = 2*err;
+    if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
+    if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
+    }  
+  }
+
   
\ No newline at end of file
index ee21b7f815bc213b04914ad5028d625512abb345..b60093c221515a4ba5db9d47035c826fb63c2afa 100644 (file)
@@ -6,13 +6,13 @@
 #include <string.h>
 #include <util/delay.h>
 #include <avr/pgmspace.h>
-
+#include <stdlib.h>
 
 /*****************************************************************************
  * BEGIN CONFIG BLOCK
  *****************************************************************************/
-#define LCD_WIDTH   240
-#define LCD_HEIGHT  320
+#define LCD_WIDTH   320
+#define LCD_HEIGHT  240
 
 //Should chip select (CS) be used?
 #define LCD_USE_CHIPSELECT  1
@@ -61,12 +61,18 @@ extern void init_spi_lcd(void);
 //Color struct - no bit fields are used for better performance (i.e. bit shifts
 //can be done while waiting for SPI, not while preparing to write the pixel)
 typedef struct {
-    uint8_t red;
-    uint8_t green;
-    uint8_t blue;
+    uint8_t c1;
+    uint8_t c2;
     } color_t;
 
 
+#define lcd_data(c) spi_wait_for_idle();LCD_DATA();spi_write(c)
+#define lcd_data_cont(c) spi_wait_for_idle();spi_write(c)
+#define lcd_command(c) spi_wait_for_idle();LCD_CMD();spi_write(c)
+
+  color_t foreground;
+  color_t background;
+    
 /*****************************************************************************
  * Public Functions
  *****************************************************************************/
@@ -74,13 +80,16 @@ typedef struct {
  void lcd_init(void);
 
 //write data word or command to the LCD
- void lcd_data      (uint8_t data);
- void lcd_command   (uint8_t cmd);
+//  void lcd_data      (uint8_t data) ;
+//  void lcd_command   (uint8_t cmd);
  void lcd_command_1 (uint8_t cmd, uint8_t data);
 
 //Set the drawing and background colors
  void lcd_set_foreground(uint8_t r, uint8_t g, uint8_t b);
  void lcd_set_background(uint8_t r, uint8_t g, uint8_t b);
+ void lcd_set_color(color_t* color, uint8_t r, uint8_t g, uint8_t b);
+ void lcd_use_foreground(color_t color);
+ void lcd_use_background(color_t color);
   
 //set display area for next write accesses
  void lcd_set_page(uint16_t start, uint16_t end);
@@ -91,10 +100,12 @@ typedef struct {
 
 //Set a pixel at a given location to the foreground color
  void lcd_set_pixel_xy(uint16_t column, uint16_t page); 
+ void lcd_set_pixel_col_xy(uint16_t column, uint16_t page, color_t col);
 //Set an area to the background color
  void lcd_set_area_xy(uint16_t col0, uint16_t col1, uint16_t page0, uint16_t page1);
 
+//Draw a straight line 
+ void lcd_draw_line(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2);
  
  
 //Text functions are included in font.c / font.h
@@ -108,7 +119,7 @@ typedef struct {
  extern uint16_t lcd_current_column;
  static inline uint16_t lcd_get_position_page(void)   {return lcd_current_page;}
  static inline uint16_t lcd_get_position_column(void) {return lcd_current_column;}
- void lcd_write_font_byte(uint8_t b);
+ void lcd_write_font_byte(uint8_t b, uint8_t c);
 
 
 /*****************************************************************************
index 92553811de12579a5058705ece3486b4b1253015..fb426792a3ff342f70053241ef5155d4538e675d 100644 (file)
@@ -1,17 +1,19 @@
-
-
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include <avr/io.h>
-#include <avr/eeprom.h>
-#include <string.h>
-
 #include "main.h"
 #include "lcdlib/lcd-color-graphic.h"
 #include "lcdlib/font.h"
 
+volatile uint16_t control_reg;
+volatile uint16_t time;
+volatile uint8_t  keys_pressed = 0b00000000;
+volatile uint8_t  next_step = 0;
+
+volatile uint8_t measurement_active = 0;
 
+color_t col_background;
+color_t col_font;
+color_t col_title;
 
+struct calib_t calib_settings;
 
 /******************
  * Init USART for LCD
@@ -20,14 +22,45 @@ void init_spi_lcd(void) {
   UCSR1B = (1 << TXEN1);
   UCSR1C = (1 << UMSEL10) | (0 << UDORD1) | (0 << UCPHA1) | (0 << UCPOL1);
   UBRR1L = 0;
-  UBRR1H = 0;
+  UBRR1H = 0; //full speed
 }
 
+/******************
+ * Read calibration from eeprom
+ *****************/
+void read_calib() {
+  for(uint8_t i=0; i< 8; i++) {
+    calib_settings.offset_res[i] = eeprom_read(i);
+    }
+  calib_settings.gain_res = eeprom_read(8);  
+  }
 
+/******************
+ * Some stuff on the LCD
+ *****************/
+void lcd_design(void) {
+  lcd_set_color(&col_background,0x03,0x04,0x05);
+  lcd_set_color(&col_title,     0x1f,0x3f,0x08);
+  lcd_set_color(&col_font,      0x1f,0x3f,0x08);
+  
+  lcd_use_background(col_background);
+  lcd_use_foreground(col_title);
+  lcd_set_area_xy(0, 0x13F, 0, 0xEF); 
+  
+  lcd_set_font(FONT_PROP_16,DOUBLE_SIZE|SPACING);
+  lcd_putstr_xy_P(PSTR("PT100 Reader"),0,0);
+  
+  }
+  
+void lcd_update(void) {
+  }
+  
+  
 /******************
  * Init all functions
  *****************/
 void init(void) {
+//CPU Regs
   
 //Init ADC SPI
   SPCR  = (0 << SPIE) | (1 << SPE ) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0 << SPR0);
@@ -40,7 +73,8 @@ void init(void) {
   DIDR0  = 0x08;  //PA3 is analog only
 
 //Init UART  
+  UCSR0B = (1 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (1 << RXEN0) | ( 1 << TXEN0); //udrie enabled on request
+  UBRR0  = 12; //38400baud
   
 //GPIO
   PORTD |= (0xc0);  //pull-up for switches
@@ -50,15 +84,66 @@ void init(void) {
   DDRA  |= (0x70);  //select outputs
   DDRC  |= (0xc0);  //outputs for Inhibit signals
   
+//Timer0: 2ms interrupts
+  TCCR0A = (2 << WGM00); //CTC
+  TCCR0B = (3 << CS00); //fcpu/64
+  OCR0A  = 249; 
+  TIMSK0 = (1 << OCF0A); //Interrupt on compare match
+
+//Timer1: 1s ticks to start measurement
+  TCCR1A = 0;
+  TCCR1B = (1 << WGM12) | ( 4 << CS10); //CTC, fcpu/256
+  TIMSK1 = (1 << OCIE1A);
+  OCR1A  = 31250;
+  
+  lcd_init();
+  lcd_command_1(LCD_MIRROR, LCD_BGR | LCD_FLIP_XY);
+  lcd_command(LCD_ON);    
+   
+  read_calib();
+  lcd_design();
+  sei();
+}
+
+
+/**********************
+ * ADC finished conversion
+ *********************/ 
+ISR(ADC_vect) {
   
 }
 
 
+/**********************
+ * 500 Hz ticks
+ *********************/ 
+ISR(TIMER0_COMPA_vect) {
+  time++;
+  next_step = 1;
+  }
+
+
+/**********************
+ * Second ticks
+ *********************/ 
+ISR(TIMER1_COMPA_vect) {
+  send_information();
+  measurement_active = 1;
+}
+
+
 int main(void) {
   
  init();
- lcd_init();
 
- while(1);
+ while(1) {
+   while(next_step==0);
+   next_step = 0;
+   if (measurement_active) {do_measurement_step();}
+   if (time == 40)         {lcd_update();}
+   if(key_was_pressed(1<<KEY_1)) {}
+   if(key_was_pressed(1<<KEY_2)) {}
+   
+   };
  return 0;
 }
\ No newline at end of file
index ce689988e6514874715646f9b67bbe6fa2fef8fd..db9cd288886569e2a20db3f5eb32eda9661a8349 100644 (file)
@@ -1,6 +1,10 @@
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/eeprom.h>
+#include <string.h>
 
-
-#define FIRMWARE_VERSION 0x01
+#define FIRMWARE_VERSION 0x0001
 
 #define UDORD1 2
 #define UCPHA1 1
 #define ADC_SELECT()     PORTB &= ~(1<< PB4)
 #define ADC_UNSELECT()   PORTB |=  (1<< PB4)
 
-#define LED1_ON()         PORTB |=  (1<< PB1)
+#define LED1_ON()         PORTB |=  (1<< PB1) //while measurement ongoing
 #define LED1_OFF()        PORTB &= ~(1<< PB1)
-#define LED2_ON()         PORTB |=  (1<< PB0)
+#define LED2_ON()         PORTB |=  (1<< PB0) //while transmitting data
 #define LED2_OFF()        PORTB &= ~(1<< PB0)
 
-#define SWITCH1()         ((PIND>>PD6)&1)
-#define SWITCH2()         ((PIND>>PD7)&1)
+
+#define KEYPORT    PORTD
+#define KEYDDR     DDRD
+#define KEYPIN     PIND
+#define KEY_1      PD6
+#define KEY_2      PD7
+#define ACTIVE_KEYS_MASK (1<<KEY_1|1<<KEY_2)
+
 
 #define SELECT(i)         (PORTA = (PORTA & 0x8F) | (((i)&0x7) << 4)
 
 #define MUX_C_ON()        PORTC &= ~(1<<PC7)
 #define MUX_C_OFF()       PORTC |=  (1<<PC7)
 #define MUX_T_ON()        PORTC &= ~(1<<PC6)
-#define MUX_T_OFF()       PORTC |=  (1<<PC6)
\ No newline at end of file
+#define MUX_T_OFF()       PORTC |=  (1<<PC6)
+
+
+void eeprom_write(uint8_t addr, uint8_t value);
+uint16_t eeprom_read(uint8_t addr);
+
+void send_answer_hex(uint8_t type, uint8_t chan, uint32_t v);
+void send_information(void);
+void read_calib(void);
+
+uint8_t key_was_pressed(uint8_t key_mask);
+
+void do_measurement_step(void);
+
+extern volatile uint16_t control_reg;
+extern volatile uint8_t keys_pressed;
+extern uint8_t  connected_sensors;
+extern volatile uint16_t time;
+extern volatile uint8_t  measurement_active;
+
+struct calib_t {
+  uint16_t    offset_res[8];
+  uint16_t    gain_res;
+  };
diff --git a/pt100/tempmeas.c b/pt100/tempmeas.c
new file mode 100644 (file)
index 0000000..3c9baf5
--- /dev/null
@@ -0,0 +1,34 @@
+#include "main.h"
+
+
+uint8_t connected_sensors = 0x1a;
+
+//measurement_active gets set once per second
+//do_measurement_step is called once every 2ms by main as long as measurement_active is set.
+//'time' gives the number of the current step
+//when done, set measurement_active to 0
+
+//calibration data is in 'calib_settings'
+
+//Step / TODO:
+//0 select channel
+//1 start internal ADC for presence
+//1 start ADC conversion
+//2 unselect channel
+//2 read ADC measurement & presence
+//2 do calibration
+//2 send information
+//3 sleep
+//... repeat 8 times
+//32 read ADC temperature as 9th channel
+//33 send ADC temperature, finished
+
+void do_measurement_step(void) {
+  if(time == 0) {
+   LED1_ON();
+   }
+  else if(time == 34) {
+    measurement_active = 0;
+    LED1_OFF();
+    }
+  }
diff --git a/pt100/uart.c b/pt100/uart.c
new file mode 100644 (file)
index 0000000..80e84e0
--- /dev/null
@@ -0,0 +1,146 @@
+
+//all data is in hex format
+//b: Board ID  -- 
+    //last board in chain is 0. b gets decreased by 1 in every uC, command is executed if b is 0. values 0..9
+    //answers: message is started with b=0, increased with every step
+//c: Channel
+
+//10 words send for each measurement:
+//ATbcXXXXXX    -- Measured temperature. value is temperature in mK
+//ATb800XXXX    -- Temperature given by ADC
+//AIb0FFFFCC    -- Firmware version & connected channels (bitmask) in last byte
+
+//Commands sent by user
+//WEb0AAXXXX     -- write int16 to eeprom at address AA*2
+//WRb0000000     -- reload eeprom data
+//WCb000XXXX     -- control register, t.b.d.
+
+#include "main.h"
+
+#define TX_BUSY()  (txcnt != 0)
+#define STARTTX(i) txcnt = (i);UCSR0B |= (1<< UDRIE0)
+#define ISMYADDR() (rxbuf[1] == '0')
+
+uint8_t rxcnt = 0, txpoint = 0;
+volatile uint8_t  txcnt = 0;
+uint8_t rxbuf[15];
+uint8_t txbuf[15];
+
+
+
+uint8_t nib_to_hex(uint32_t in, uint8_t nib) {
+  uint8_t t = (in >> (nib*4)) & 0xF;
+  if (t <= 9) {return t + 0x30;}
+  return t - 10 + 0x61;
+  }
+uint8_t hex_to_int(uint8_t h) { //assumes valid number
+  if (h < 0x40) return h-0x30;
+  if (h < 0x50) return h-0x41+10;
+                return h-0x61+10;
+  }
+
+uint8_t hex_to_byte(uint8_t* h) {
+  return hex_to_int(*h)*16 + hex_to_int(*(h+1));
+  }
+  
+  
+void forward_msg(uint8_t i) {
+  if(rxbuf[0] == 'A') rxbuf[1]++;
+  else                rxbuf[1]--;
+  memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,i);
+  STARTTX(i);
+  }  
+  
+  
+uint8_t is_my_address(uint8_t s) {
+  if (ISMYADDR() && rxbuf[0] != 'A') {
+    return 1;
+    }
+  else {
+    forward_msg(s);
+    return 0;
+    }
+  }
+
+void send_answer_hex(uint8_t type, uint8_t chan, uint32_t v) {
+  sei();
+  while(TX_BUSY());
+  txbuf[0]='A';
+  txbuf[1]=type;
+  txbuf[2]='0';
+  txbuf[3]=chan;
+  txbuf[4]=nib_to_hex(v,5);
+  txbuf[5]=nib_to_hex(v,4);
+  txbuf[6]=nib_to_hex(v,3);
+  txbuf[7]=nib_to_hex(v,2);
+  txbuf[8]=nib_to_hex(v,1);
+  txbuf[9]=nib_to_hex(v,0);
+  txbuf[10]='\n';
+  STARTTX(11);
+  }  
+
+  
+void send_information(void) {
+  sei();
+  while(TX_BUSY());
+  txbuf[0]='A';
+  txbuf[1]='I';
+  txbuf[2]='0';
+  txbuf[3]='0';
+  txbuf[4]=nib_to_hex(FIRMWARE_VERSION,3);
+  txbuf[5]=nib_to_hex(FIRMWARE_VERSION,2);
+  txbuf[6]=nib_to_hex(FIRMWARE_VERSION,1);
+  txbuf[7]=nib_to_hex(FIRMWARE_VERSION,0);
+  txbuf[8]=nib_to_hex(connected_sensors,1);
+  txbuf[9]=nib_to_hex(connected_sensors,0);
+  txbuf[10]='\n';
+  STARTTX(11);  
+  }
+  
+/**********************
+ * UART received a byte
+ *********************/ 
+ISR(USART0_RX_vect) {
+  uint8_t buf = UDR1;
+  if (rxcnt != 0 || (buf == 'W' || buf == 'A')) {
+    rxbuf[rxcnt++] = buf;
+    }
+  if (buf == '\n' || buf == '\r') {
+    if(rxcnt == 11) {
+      if(rxbuf[0] == 'A') {forward_msg(rxcnt);}
+      else if(rxbuf[0] == 'W') {
+        if(rxbuf[1] == 'E') {
+          uint8_t addr = hex_to_byte(rxbuf+4);
+          eeprom_write(addr,  (hex_to_byte(rxbuf+6)<<8) | hex_to_byte(rxbuf+8));
+          }
+        else if(rxbuf[1] == 'C') {
+          control_reg = (hex_to_byte(rxbuf+6)<<8) | hex_to_byte(rxbuf+8);
+          }
+        else if(rxbuf[1] == 'R') {
+          read_calib();
+          }
+        }
+      }
+    else {
+      rxcnt = 0;
+      }
+    }
+  if (rxcnt >= 12 || buf == '\n' || buf == '\r') { 
+    rxcnt = 0; 
+    }  
+  }
+
+/**********************
+ * UART able to send a byte
+ *********************/ 
+ISR(USART0_UDRE_vect) {
+  LED2_ON();
+  UDR0 = txbuf[txpoint++];
+  if(--txcnt == 0 || txpoint > 12) {  
+    txpoint = 0;
+    txcnt = 0;
+    UCSR0B &= ~(1<< UDRIE0);
+    LED2_OFF();
+    }
+  }
\ No newline at end of file