Commit 89804505 authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Added the initial version of the pattern frame buffer module.

parent 70a199c0
# setup
# modified by zerom for WinARM 8/2010
COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork
COMPILE_OPTS += -Wall -O2 -fno-common
#COMPILE_OPTS += -Wall -g -fno-common
COMPILE_OPTS += -ffreestanding -nostdlib
COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4
COMPILE_OPTS_M0 = -mfloat-abi=softfp -mcpu=cortex-m0
COMPILE_OPTS_M0plus = -mfloat-abi=softfp -mcpu=cortex-m0plus
COMPILE_OPTS_M3 = -mfloat-abi=softfp -mcpu=cortex-m3
INCLUDE_DIRS = -I./include/ -I../memory/include -I../scheduler/include
DOC_DIR = ./doc
TCHAIN_PREFIX=arm-none-eabi-
CC = $(TCHAIN_PREFIX)gcc
CFLAGS = $(COMPILE_OPTS) $(INCLUDE_DIRS)
AR = $(TCHAIN_PREFIX)ar
ARFLAGS = cr
PATTERN_FB_OUT_M4_FPU = ./lib/pattern_fb_m4_fpu.a
PATTERN_FB_OUT_M0 = ./lib/pattern_fb_m0.a
PATTERN_FB_OUT_M0plus = ./lib/pattern_fb_m0plus.a
PATTERN_FB_OUT_M3 = ./lib/pattern_fb_m3.a
SRC_DIR=./src/
SRC=$(wildcard $(SRC_DIR)*.c)
PATTERN_FB_M4_FPU_OBJ_DIR=build/m4_fpu/
PATTERN_FB_M4_FPU_OBJS_TMP = $(notdir $(SRC:.c=.o))
PATTERN_FB_M4_FPU_OBJS = $(patsubst %,$(PATTERN_FB_M4_FPU_OBJ_DIR)%,$(PATTERN_FB_M4_FPU_OBJS_TMP))
PATTERN_FB_M0_OBJ_DIR=build/m0/
PATTERN_FB_M0_OBJS_TMP = $(notdir $(SRC:.c=.o))
PATTERN_FB_M0_OBJS = $(patsubst %,$(PATTERN_FB_M0_OBJ_DIR)%,$(PATTERN_FB_M0_OBJS_TMP))
PATTERN_FB_M0plus_OBJ_DIR=build/m0plus/
PATTERN_FB_M0plus_OBJS_TMP = $(notdir $(SRC:.c=.o))
PATTERN_FB_M0plus_OBJS = $(patsubst %,$(PATTERN_FB_M0plus_OBJ_DIR)%,$(PATTERN_FB_M0plus_OBJS_TMP))
PATTERN_FB_M3_OBJ_DIR=build/m3/
PATTERN_FB_M3_OBJS_TMP = $(notdir $(SRC:.c=.o))
PATTERN_FB_M3_OBJS = $(patsubst %,$(PATTERN_FB_M3_OBJ_DIR)%,$(PATTERN_FB_M3_OBJS_TMP))
all: $(PATTERN_FB_OUT_M4_FPU) $(PATTERN_FB_OUT_M0) $(PATTERN_FB_OUT_M0plus) $(PATTERN_FB_OUT_M3)
$(PATTERN_FB_M4_FPU_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M4_FPU) -o $@ $<
$(PATTERN_FB_M0_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0) -o $@ $<
$(PATTERN_FB_M0plus_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0plus) -o $@ $<
$(PATTERN_FB_M3_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M3) -o $@ $<
mkdir_build:
mkdir -p build/m4_fpu
mkdir -p build/m0
mkdir -p build/m0plus
mkdir -p build/m3
$(PATTERN_FB_OUT_M4_FPU): mkdir_build $(PATTERN_FB_M4_FPU_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(PATTERN_FB_M4_FPU_OBJS)
$(PATTERN_FB_OUT_M0): mkdir_build $(PATTERN_FB_M0_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(PATTERN_FB_M0_OBJS)
$(PATTERN_FB_OUT_M0plus): mkdir_build $(PATTERN_FB_M0plus_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(PATTERN_FB_M0plus_OBJS)
$(PATTERN_FB_OUT_M3): mkdir_build $(PATTERN_FB_M3_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(PATTERN_FB_M3_OBJS)
doc:
doxygen $(DOC_DIR)/doxygen.conf
clean:
rm -f $(PATTERN_FB_M4_FPU_OBJS)
rm -f $(PATTERN_FB_M0_OBJS)
rm -f $(PATTERN_FB_M0plus_OBJS)
rm -f $(PATTERN_FB_M3_OBJS)
rm -rf lib
rm -rf build
rm -rf doc/html
.PHONY: all clean doc
#ifndef _FRAME_BUFFER_H
#define _FRAME_BUFFER_H
#ifdef __cplusplus
extern "C" {
#endif
#include "memory.h"
#include "frame_buffer_registers.h"
#ifndef FB_MAX_BUFFER_LEN
#define FB_MAX_BUFFER_LEN 16*1024
#endif
#define BYTES_PER_PIXEL 3
#define LEDS_BYTES_PER_PIXEL 12
unsigned char frame_buffer_init(TFrameBuffer *fb,TMemory *memory);
void frame_buffer_set_num_rows(TFrameBuffer *fb,unsigned short int rows);
unsigned short int frame_buffer_get_num_rows(TFrameBuffer *fb);
void frame_buffer_set_pixels_per_row(TFrameBuffer *fb,unsigned short int pixels);
unsigned short int frame_buffer_get_pixels_per_row(TFrameBuffer *fb);
void frame_buffer_set_num_buffers(TFrameBuffer *fb,unsigned char num);
unsigned char frame_buffer_get_num_buffers(TFrameBuffer *fb);
unsigned short int frame_buffer_get_free_memory(TFrameBuffer *fb);
unsigned char frame_buffer_update_buffer(TFrameBuffer *fb);
unsigned char *frame_buffer_get_pixel_buffer(TFrameBuffer *fb);
void frame_buffer_set_pixel_buffer(TFrameBuffer *fb,unsigned char *buffer);
void frame_buffer_set_pixel(TFrameBuffer *fb,unsigned char R,unsigned char G,unsigned char B,unsigned short int row,unsigned short int col, unsigned char *buffer);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _FRAME_BUFFER_REGISTERS_H
#define _FRAME_BUFFER_REGISTERS_H
#ifndef RAM_FB_BASE_ADDRESS
#define RAM_FB_BASE_ADDRESS ((unsigned short int)0x0000)
#endif
#define RAM_FB_LENGTH 2
#define FB_FREE_MEMORY (RAM_FB_BASE_ADDRESS)
#ifndef EEPROM_FB_BASE_ADDRESS
#define EEPROM_FB_BASE_ADDRESS ((unsigned short int)0x0000)
#endif
#define EEPROM_FB_LENGTH 6
#define FB_NUM_ROWS (EEPROM_FB_BASE_ADDRESS)
#define FB_NUM_PIXELS (EEPROM_FB_BASE_ADDRESS+2)
#define FB_NUM_BUFFERS (EEPROM_FB_BASE_ADDRESS+4)
#ifndef DEFAULT_FB_NUM_ROWS
#define DEFAULT_FB_NUM_ROWS 0x0004
#endif
#ifndef DEFAULT_FB_NUM_PIXELS
#define DEFAULT_FB_NUM_PIXELS 0x0030
#endif
#ifndef DEFAULT_FB_NUM_BUFFERS
#define DEFAULT_FB_NUM_BUFFERS 0x0001
#endif
#define frame_buffer_eeprom_data(name,section_name) \
unsigned short int name##_eeprom_data[] __attribute__ ((section (".section_nane")))={DEFAULT_FB_NUM_ROWS&0x00FF,FB_NUM_ROWS, \
(DEFAULT_FB_NUM_ROWS>>8)&0x00FF,FB_NUM_ROWS+1, \
DEFAULT_FB_NUM_PIXELS&0x00FF,FB_NUM_PIXELS, \
(DEFAULT_FB_NUM_PIXELS>>8)&0x00FF,FB_NUM_PIXELS+1, \
DEFAULT_FB_NUM_BUFFERS&0x00FF,FB_NUM_BUFFERS, \
(DEFAULT_FB_NUM_BUFFERS>>8)&0x00FF,FB_NUM_BUFFERS+1}; \
#endif
#ifndef IMAGE_PATTERNS_H
#define IMAGE_PATTERNS_H
#include "patterns.h"
#include "memory.h"
#ifndef MAX_NUM_IMAGES
#define MAX_NUM_IMAGES 1
#endif
#ifndef MAX_IMAGE_WIDTH
#define MAX_IMAGE_WIDTH 15
#endif
#ifndef MAX_IMAGE_HEIGHT
#define MAX_IMAGE_HEIGHT 15
#endif
#include "image_patterns_registers.h"
#define IMAGE_GROUP 0x20
unsigned char img_patterns_init(TMemory *memory);
#pragma pack (push, 1)
typedef struct
{
short int start_row;
short int start_col;
unsigned char buffer_id;
unsigned char waveform_index;
unsigned char motion_index;
}TIMGDisplayData;
#pragma pack (pop)
#define IMG_ID_OFFSET 0x01
#define IMG_START_ROW_OFFSET 0
#define IMG_START_COL_OFFSET 2
#define IMG_BUFFER_ID_OFFSET 4
#define IMG_WF_INDEX_OFFSET 5
#define IMG_MTN_INDEX_OFFSET 6
void img_general(TLEDArea *area,TIMGDisplayData *pattern_data,unsigned short int period,unsigned char *buffer);
#endif
#ifndef _IMAGE_PATTERNS_REGISTERS_H
#define _IMAGE_PATTERNS_REGISTERS_H
#ifndef RAM_IMG_PATTERNS_BASE_ADDRESS
#define RAM_IMG_PATTERNS_BASE_ADDRESS ((unsigned short int)0x0000)
#endif
#define RAM_IMG_PATTERNS_LENGTH MAX_NUM_IMAGES*MAX_IMAGE_WIDTH*MAX_IMAGE_HEIGHT*3+3
#define IMG_PATTERNS_MAX_WIDTH (RAM_IMG_PATTERNS_BASE_ADDRESS)
#define IMG_PATTERNS_MAX_HEIGHT (RAM_IMG_PATTERNS_BASE_ADDRESS+1)
#define IMG_PATTERNS_NUM_IMGS (RAM_IMG_PATTERNS_BASE_ADDRESS+2)
#define IMG_PATTERNS_DATA (RAM_IMG_PATTERNS_BASE_ADDRESS+3)
#endif
#ifndef _LED_CONTROL_H
#define _LED_CONTROL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx.h"
#include "patterns.h"
#include "memory.h"
#ifndef MAX_PATTERN_FUNC
#define MAX_PATTERN_FUNC 16
#endif
#ifndef MAX_DATA_PATTERN_LEN
#define MAX_DATA_PATTERN_LEN 32
#endif
#include "led_control_registers.h"
typedef void (*pattern_func_t)(TLEDArea *area,void *pattern_data,uint16_t period,unsigned char *buffer);
typedef struct
{
unsigned char num_patterns;
pattern_func_t functions[MAX_PATTERN_FUNC];
TLEDArea area[MAX_PATTERN_FUNC];
unsigned char parameters[MAX_PATTERN_FUNC][MAX_DATA_PATTERN_LEN];
}TPatterns;
unsigned char led_control_init(TMemory *memory);
unsigned char led_control_add_pattern(pattern_func_t function,TLEDArea *area,void *data,unsigned char data_length);
void led_control_remove_pattern(unsigned char index);
void led_control_clear_patterns(void);
unsigned char led_control_get_num_patterns(void);
unsigned char *led_control_get_parameters(unsigned char index);
void led_control_loop(void);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _LED_CONTROL_REGISTERS_H
#define _LED_CONTROL_REGISTERS_H
#ifndef RAM_LED_CONTROL_BASE_ADDRESS
#define RAM_LED_CONTROL_BASE_ADDRESS ((unsigned short int)0x0000)
#endif
#define RAM_LED_CONTROL_LENGTH 12+MAX_DATA_PATTERN_LEN
#define LED_CONTROL_NUM_PATTERN (RAM_LED_CONTROL_BASE_ADDRESS)
#define LED_CONTROL_PATTERN_INDEX (RAM_LED_CONTROL_BASE_ADDRESS+1)
#define LED_CONTROL (RAM_LED_CONTROL_BASE_ADDRESS+2)
#define LED_CONTROL_PATTERN_ID (RAM_LED_CONTROL_BASE_ADDRESS+3)
#define LED_CONTROL_MIN_ROW (RAM_LED_CONTROL_BASE_ADDRESS+4)
#define LED_CONTROL_MAX_ROW (RAM_LED_CONTROL_BASE_ADDRESS+6)
#define LED_CONTROL_MIN_COL (RAM_LED_CONTROL_BASE_ADDRESS+8)
#define LED_CONTROL_MAX_COL (RAM_LED_CONTROL_BASE_ADDRESS+10)
#define LED_CONTROL_DATA (RAM_LED_CONTROL_BASE_ADDRESS+12)
#define LED_CONTROL_LOAD 0x01
#define LED_CONTROL_REMOVE 0x02
#define LED_CONTROL_CLEAR 0x04
#endif
#ifndef _MOTION_PATTERNS_H
#define _MOTION_PATTERNS_H
#include "patterns.h"
#ifndef MTN_X_LED_SPACING
#define MTN_X_LED_SPACING 10
#endif
#ifndef MTN_Y_LED_SPACING
#define MTN_Y_LED_SPACING 10
#endif
#define MOTION_GROUP 0x30
typedef enum {MTN_RAMP=0x01,MTN_TRIANGLE=0x02,MTN_CIRCLE=0x03,MTN_NONE=0x04} mtn_id_t;
typedef struct
{
short int max_coord_x;
short int max_coord_y;
short int min_coord_x;
short int min_coord_y;
unsigned char direction;
}TMTNRampData;
typedef struct
{
short int max_coord_x;
short int max_coord_y;
short int min_coord_x;
short int min_coord_y;
unsigned char direction;
}TMTNTriangleData;
typedef struct
{
short int radius_mm;
short int center_x;
short int center_y;
short int dummy1;
unsigned char dummy2;
}TMTNCircleData;
typedef union
{
TMTNRampData ramp_data;
TMTNTriangleData triangle_data;
TMTNCircleData circle_data;
}TMTNData;
#pragma pack (push, 1)
typedef struct
{
mtn_id_t motion_id;
unsigned short int speed_mm_s;
TMTNData motion_data;
// internal data
short int current_col;
short int current_row;
unsigned short int current_time;
}TMotion;
#pragma pack (pop)
#define MTN_ID_OFFSET 0
#define MTN_SPEED_OFFSET 1
#define MTN_DATA 3
#define MTN_CURRENT_COL_OFFSET 12
#define MTN_CURRENT_ROW_OFFSET 14
#define MTN_CURRENT_TIME_OFFSET 16
void mtn_general(TLEDArea *area,TMotion *pattern_data,unsigned short int period,unsigned char *buffer);
void mtn_compute(TMotion *pattern_data);
#endif
#ifndef PATTERNS_H
#define PATTERNS_H
#define PATTERN_GROUP 0xF0
#define PATTERN_ID 0x0F
typedef struct
{
unsigned short int min_row;
unsigned short int max_row;
unsigned short int min_col;
unsigned short int max_col;
}TLEDArea;
typedef struct
{
unsigned char R;
unsigned char G;
unsigned char B;
}TPixelRGB;
#endif
#ifndef WAVEFORM_PATTERNS_H
#define WAVEFORM_PATTERNS_H
#include "patterns.h"
#define WAVEFORM_GROUP 0x10
typedef enum {WF_SINE=0x01,WF_SQUARE=0x02,WF_RAMP=0x03,WF_TRIANGLE=0x04,WF_NONE=0x05} wf_id_t;
typedef struct
{
unsigned short int phase;
}TWFSineData;
typedef struct
{
unsigned short int t_on;
}TWFSquareData;
typedef struct
{
unsigned short int dummy;
}TWFRampData;
typedef struct
{
unsigned short int dummy;
}TWFTriangleData;
typedef union{
TWFSineData sine_data;
TWFSquareData square_data;
TWFRampData ramp_data;
TWFTriangleData trinagle_data;
}TWFData;
#pragma pack (push, 1)
typedef struct
{
wf_id_t waveform_id;
TPixelRGB max;
TPixelRGB min;
unsigned short int period;
TWFData data;
unsigned char active;
// internal data (static)
unsigned short int current_period;
}TWaveform;
#pragma pack (pop)
#define WF_ID_OFFSET 0
#define WF_MAX_R_OFFSET 1
#define WF_MAX_G_OFFSET 2
#define WF_MAX_B_OFFSET 3
#define WF_MIN_R_OFFSET 4
#define WF_MIN_G_OFFSET 5
#define WF_MIN_B_OFFSET 6
#define WF_PERIOD_OFFSET 7
#define WF_DATA_OFFSET 9
#define WF_ACTIVE 11
#define WF_CURRENT_PERIOD_OFFSET 12
void wf_general(TLEDArea *area,TWaveform *pattern_data,unsigned short int period,unsigned char *buffer);
TPixelRGB wf_pixel(TWaveform *pattern_data);
#endif
#include "frame_buffer.h"
typedef enum {FB_SRAM1,FB_SRAM2} fb_segment_t;
typedef struct
{
TMemModule *mem_module;
TScheduler *scheduler;
unsigned short int num_rows;
unsigned short int num_pixels_per_row;
unsigned short int num_buffers;
unsigned short int buffer_size;
unsigned short int free_mem;
fb_segment_t read_current_segment;
unsigned char read_current_buffer;
fb_segment_t write_current_segment;
unsigned char write_current_buffer;
unsigned char buffer1[FB_MAX_BUFFER_LEN];
unsigned char buffer2[FB_MAX_BUFFER_LEN];
unsigned char pixel_buffer[FB_MAX_BUFFER_LEN/(FB_BYTES_PER_PIXEL/FB_BYTES_PER_PIXEL)];
}TFrameBuffer;
// private functions
void fb_write_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
{
TFrameBuffer *fb=(TFrameBuffer *)module;
unsigned short int new_value;
unsigned char *data_ptr;
if(ram_in_window(FB_NUM_ROWS,2,address,length))
{
new_value=fb->num_rows;
data_ptr=(unsigned char *)&new_value;
if(ram_in_range(FB_NUM_ROWS,address,length))
data_ptr[0]=data[FB_NUM_ROWS-address];
if(ram_in_range(FB_NUM_ROWS+1,address,length))
data_ptr[1]=data[FB_NUM_ROWS+1-address];
fb_set_num_rows(new_value);
}
if(ram_in_window(FB_NUM_PIXELS,2,address,length))
{
new_value=fb->num_pixels_per_row;
data_ptr=(unsigned char *)&new_value;
if(ram_in_range(FB_NUM_PIXELS,address,length))
data_ptr[0]=data[FB_NUM_PIXELS-address];
if(ram_in_range(FB_NUM_PIXELS+1,address,length))
data_ptr[1]=data[FB_NUM_PIXELS+1-address];
fb_set_pixels_per_row(new_value);
}
if(ram_in_window(FB_NUM_BUFFERS,2,address,length))
{
new_value=fb->num_buffers;
data_ptr=(unsigned char *)&new_value;
if(ram_in_range(FB_NUM_BUFFERS,address,length))
data_ptr[0]=data[FB_NUM_BUFFERS-address];
if(ram_in_range(FB_NUM_BUFFERS+1,address,length))
data_ptr[1]=data[FB_NUM_BUFFERS+1-address];
fb_set_num_buffers(new_value);
}
}
void fb_read_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
{
ram_read_table(address,length,data);
}
void fb_compute_free_memory(TFrameBuffer *fb)
{
leds_buffer_size=leds_num_rows*leds_num_pixels_per_row*FB_BYTES_PER_PIXEL+RESET_LENGTH;
leds_free_mem=MAX_BUFFER_LEN-leds_buffer_size*leds_num_buffers;
ram_data[FB_FREE_MEMORY]=leds_free_mem&0x00FF;
ram_data[FB_FREE_MEMORY+1]=(leds_free_mem&0xFF00)>>8;
}
void leds_write_buffer(TFrameBuffer *fb,unsigned char *pixel_buffer,unsigned char *led_buffer)
{
unsigned short int i,j,k,offset_pixel,offset_leds;
unsigned char pixel_g,pixel_r,pixel_b;
for(i=0;i<leds_num_rows;i++)
{
for(j=0;j<leds_num_pixels_per_row;j++)
{
offset_pixel=(i*leds_num_pixels_per_row+j)*BYTES_PER_PIXEL;
pixel_r=pixel_buffer[offset_pixel];
pixel_g=pixel_buffer[offset_pixel+1];
pixel_b=pixel_buffer[offset_pixel+2];
if(i%2)//odd
offset_leds=((i+1)*leds_num_pixels_per_row-1-j)*FB_BYTES_PER_PIXEL;
else//even
offset_leds=(i*leds_num_pixels_per_row+j)*FB_BYTES_PER_PIXEL;
for(k=0;k<4;k++)
{
if(pixel_g&(0x80>>(k*2)))
led_buffer[offset_leds+k]=0xC0;
else
led_buffer[offset_leds+k]=0x80;
if(pixel_g&(0x80>>((k*2)+1)))
led_buffer[offset_leds+k]|=0x0C;
else
led_buffer[offset_leds+k]|=0x08;
if(pixel_r&(0x80>>(k*2)))
led_buffer[offset_leds+(k+4)]=0xC0;
else
led_buffer[offset_leds+(k+4)]=0x80;
if(pixel_r&(0x80>>((k*2)+1)))
led_buffer[offset_leds+(k+4)]|=0x0C;
else
led_buffer[offset_leds+(k+4)]|=0x08;
if(pixel_b&(0x80>>(k*2)))
led_buffer[offset_leds+(k+8)]=0xC0;
else
led_buffer[offset_leds+(k+8)]=0x80;
if(pixel_b&(0x80>>((k*2)+1)))
led_buffer[offset_leds+(k+8)]|=0x0C;
else
led_buffer[offset_leds+(k+8)]|=0x08;
}
pixel_buffer[offset_pixel]=0x00;
pixel_buffer[offset_pixel+1]=0x00;
pixel_buffer[offset_pixel+2]=0x00;
}
}
}
void leds_write_reset(TFrameBuffer *fb,unsigned char *led_buffer)
{
unsigned short int i;
for(i=0;i<RESET_LENGTH;i++)
led_buffer[leds_num_rows*leds_num_pixels_per_row*FB_BYTES_PER_PIXEL+i]=0x00;
}