diff --git a/pattern_frame_buffer/Makefile b/pattern_frame_buffer/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..3be4be6c6d07b77d8897994428ed716654cf8366 --- /dev/null +++ b/pattern_frame_buffer/Makefile @@ -0,0 +1,89 @@ +# 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 diff --git a/pattern_frame_buffer/include/frame_buffer.h b/pattern_frame_buffer/include/frame_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..edf28ebf3b9ee5e993060749835fcb8d8b432177 --- /dev/null +++ b/pattern_frame_buffer/include/frame_buffer.h @@ -0,0 +1,36 @@ +#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 diff --git a/pattern_frame_buffer/include/frame_buffer_registers.h b/pattern_frame_buffer/include/frame_buffer_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..40c70306879ae7c0c13bbb6ebb448de5bd29c34d --- /dev/null +++ b/pattern_frame_buffer/include/frame_buffer_registers.h @@ -0,0 +1,40 @@ +#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 + diff --git a/pattern_frame_buffer/include/image_patterns.h b/pattern_frame_buffer/include/image_patterns.h new file mode 100644 index 0000000000000000000000000000000000000000..fe385c1e2c2f009b4e4afba0f1b5500ecfeb4fa8 --- /dev/null +++ b/pattern_frame_buffer/include/image_patterns.h @@ -0,0 +1,45 @@ +#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 diff --git a/pattern_frame_buffer/include/image_patterns_registers.h b/pattern_frame_buffer/include/image_patterns_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..bf3e8b9146ab3bcc1695e7e7cc7810e445d4ee27 --- /dev/null +++ b/pattern_frame_buffer/include/image_patterns_registers.h @@ -0,0 +1,16 @@ +#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 + diff --git a/pattern_frame_buffer/include/led_control.h b/pattern_frame_buffer/include/led_control.h new file mode 100644 index 0000000000000000000000000000000000000000..c5a30f0ef62dd2c05c01987aca8278842ca33fc3 --- /dev/null +++ b/pattern_frame_buffer/include/led_control.h @@ -0,0 +1,44 @@ +#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 diff --git a/pattern_frame_buffer/include/led_control_registers.h b/pattern_frame_buffer/include/led_control_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..18f73d8986a839c18e47ee8413c6642e74b5a6b6 --- /dev/null +++ b/pattern_frame_buffer/include/led_control_registers.h @@ -0,0 +1,25 @@ +#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 + diff --git a/pattern_frame_buffer/include/motion_patterns.h b/pattern_frame_buffer/include/motion_patterns.h new file mode 100644 index 0000000000000000000000000000000000000000..39a8a1d3162d37e12b765e2fcc439548401de129 --- /dev/null +++ b/pattern_frame_buffer/include/motion_patterns.h @@ -0,0 +1,75 @@ +#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 diff --git a/pattern_frame_buffer/include/patterns.h b/pattern_frame_buffer/include/patterns.h new file mode 100644 index 0000000000000000000000000000000000000000..bbf52cf8e0280b5d5804ea7c626ae37cd0be73bf --- /dev/null +++ b/pattern_frame_buffer/include/patterns.h @@ -0,0 +1,24 @@ +#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 diff --git a/pattern_frame_buffer/include/waveform_patterns.h b/pattern_frame_buffer/include/waveform_patterns.h new file mode 100644 index 0000000000000000000000000000000000000000..ad5bab637fc93c94d1be19c2d9d8b2304686cac4 --- /dev/null +++ b/pattern_frame_buffer/include/waveform_patterns.h @@ -0,0 +1,66 @@ +#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 diff --git a/pattern_frame_buffer/src/frame_buffer.c b/pattern_frame_buffer/src/frame_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..7cdf725562c0a5cbbd363d8072c30053c0aebc5e --- /dev/null +++ b/pattern_frame_buffer/src/frame_buffer.c @@ -0,0 +1,296 @@ +#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; +} + +/* Interrupt handlers */ +void leds_scheduler(void) +{ + unsigned char *start_address; + + /* switch to the next buffer*/ + if(leds_spi_current_buffer>=leds_num_buffers) + { + leds_spi_current_buffer=0; + if(leds_spi_current_segment==FB_SRAM1) + { + leds_spi_current_segment=FB_SRAM2; + start_address=&leds_buffer2[0]; + } + else + { + leds_spi_current_segment=FB_SRAM1; + start_address=&leds_buffer1[0]; + } + } + else + { + if(leds_spi_current_segment==FB_SRAM1) + start_address=&leds_buffer1[leds_spi_current_buffer*leds_buffer_size]; + else + start_address=&leds_buffer2[leds_spi_current_buffer*leds_buffer_size]; + } + leds_spi_current_buffer++; + HAL_SPI_Transmit_DMA(&led_spi,start_address,leds_buffer_size); + leds_update=0x01; +} + +// public functions +unsigned char fb_init(TFrameBuffer *fb,TMemory *memory) +{ + unsigned int i; + + /* initialize internal data */ + fb_set_period(fb,DEFAULT_FB_PERIOD); + fb_set_num_rows(fb,DEFAULT_FB_NUM_ROWS); + fb_set_pixels_per_row(fb,DEFAULT_FB_NUM_PIXELS); + fb_set_num_buffers(fb,DEFAULT_FB_NUM_BUFFERS); + fb->read_current_buffer=0; + fb->read_current_segment=FB_SRAM2; + fb->write_current_buffer=0; + fb->write_current_segment=FB_SRAM2; + + for(i=0;i<FB_MAX_BUFFER_LEN/(FB_BYTES_PER_PIXEL/FB_BYTES_PER_PIXEL);i++) + fb->pixel_buffer[i]=0x00; + for(i=0;i<fb->num_buffers;i++) + { + fb_write_buffer(fb,fb->pixel_buffer,&fb->buffer1[fb->buffer_size*i]); + fb_write_reset(fb,&fb->buffer1[fb->buffer_size*i]); + fb_write_buffer(fb,fb->pixel_buffer,&fb->buffer2[fb->buffer_size*i]); + fb_write_reset(fb,&fb->buffer2[fb->buffer_size*i]); + } + + mem_module_init(&fb->mem_module); + fb->mem_module.write_cmd=fb_write_cmd; + fb->mem_module.read_cmd=fb_read_cmd; + fb->data=fb; + if(!mem_module_add_ram_segment(&fb->mem_module,RAM_FB_BASE_ADDRESS,RAM_FB_LENGTH)) + return 0x00; + if(!mem_module_add_eeprom_segment(&fb->mem_module,EEPROM_FB_BASE_ADDRESS,EEPROM_FB_LENGTH)) + return 0x00; + if(!mem_add_module(memory,&fb->mem_module)) + return 0x00; + + return 0x01; +} + +void fb_set_num_rows(TFrameBuffer *fb,unsigned short int rows) +{ + leds_num_rows=rows; + ram_data[FB_NUM_ROWS]=rows&0x00FF; + ram_data[FB_NUM_ROWS+1]=(rows&0xFF00)>>8; + leds_compute_free_memory(); +} + +unsigned short int fb_get_num_rows(TFrameBuffer *fb) +{ + return leds_num_rows; +} + +void fb_set_pixels_per_row(TFrameBuffer *fb,unsigned short int pixels) +{ + leds_num_pixels_per_row=pixels; + ram_data[FB_NUM_PIXELS]=pixels&0x00FF; + ram_data[FB_NUM_PIXELS+1]=(pixels&0xFF00)>>8; + leds_compute_free_memory(); +} + +unsigned short int fb_get_pixels_per_row(TFrameBuffer *fb) +{ + return leds_num_pixels_per_row; +} + +void fb_set_num_buffers(TFrameBuffer *fb,unsigned char num) +{ + leds_num_buffers=num; + ram_data[FB_NUM_BUFFERS]=num&0x00FF; + ram_data[FB_NUM_BUFFERS+1]=(num&0xFF00)>>8; + leds_compute_free_memory(); +} + +unsigned char fb_get_num_buffers(TFrameBuffer *fb) +{ + return leds_num_buffers; +} + +unsigned short int fb_get_free_memory(TFrameBuffer *fb) +{ + return leds_free_mem; +} + +unsigned char fb_update_buffer(TFrameBuffer *fb) +{ + if(leds_update) + { + leds_update=0x00; + return 0x01; + } + else + return 0x00; +} + +unsigned char *fb_get_pixel_buffer(TFrameBuffer *fb) +{ + return leds_pixel_buffer; +} + +void fb_set_pixel_buffer(TFrameBuffer *fb,unsigned char *buffer) +{ + if(leds_user_current_segment==FB_SRAM1) + { + leds_write_buffer(buffer,&leds_buffer1[leds_buffer_size*leds_user_current_buffer]); + leds_write_reset(&leds_buffer1[leds_buffer_size*leds_user_current_buffer]); + leds_user_current_buffer++; + if(leds_user_current_buffer>=leds_num_buffers) + { + leds_user_current_buffer=0; + leds_user_current_segment=FB_SRAM2; + } + } + else + { + leds_write_buffer(buffer,&leds_buffer2[leds_buffer_size*leds_user_current_buffer]); + leds_write_reset(&leds_buffer2[leds_buffer_size*leds_user_current_buffer]); + leds_user_current_buffer++; + if(leds_user_current_buffer>=leds_num_buffers) + { + leds_user_current_buffer=0; + leds_user_current_segment=FB_SRAM1; + } + } +} + +void fb_set_pixel(TFrameBuffer *fb,unsigned char R,unsigned char G,unsigned char B,unsigned short int row,unsigned short int col, unsigned char *buffer) +{ + buffer[((row*leds_num_pixels_per_row+col)*BYTES_PER_PIXEL)]=R; + buffer[((row*leds_num_pixels_per_row+col)*BYTES_PER_PIXEL)+1]=G; + buffer[((row*leds_num_pixels_per_row+col)*BYTES_PER_PIXEL)+2]=B; +}