Commit d08ff29d authored by crvaksda's avatar crvaksda 😁
Browse files

Made update_out_buf do stuff. Maybe it kind of works.

parent 88cdf7ad
pov
\ No newline at end of file
pov
core
\ No newline at end of file
......@@ -2,5 +2,5 @@
This repository contains all the software required to turn an old ceiling fan into a fully functional POV-display.
## Build Instructions
To build, use `$ gcc -pthread -o pov main.c pov.c spi.c`.
To build, use `$ gcc -o pov -lpthread -lm main.c spi.c pov.c`.
And then `$./pov` to run the application.
\ No newline at end of file
......@@ -32,6 +32,12 @@ int main(){
if(pov_buf && pov_buf_len){
err = pov_init();
if(err){
printf("ERROR: Fatal error encountered while initializing POV.\n");
return -1;
}
pthread_t pov_tid;
pthread_create(&pov_tid, NULL, pov_run, (void *)&pov_tid);
......
......@@ -15,9 +15,26 @@
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#include <time.h>
#include "pov.h"
fb_pixel fb[FRAME_BUFFER_SIZE];
volatile led_wing wings[NUM_WINGS] = { 0 };
struct fb_var_screeninfo orig_vinfo;
struct fb_var_screeninfo var_info;
struct fb_fix_screeninfo fixed_info;
int radii[NUM_LEDS_PER_WING]; // Holds radii in number of pixels which map to radii in number of leds.
int indices[NUM_LEDS_PER_WING][THETA_RESOLUTION]; // Holds fb-indices corresponding to (r, t)-coords.
static int set_led_pixel_color(volatile led_pixel *lp, int r, int g, int b){
uint8_t p = 0xC0;
......@@ -46,36 +63,57 @@ static int set_wing_led_color(volatile led_wing *wing, int led, uint8_t r, uint8
return -1;
}
static int update_fb(){
return 0;
}
static void get_xy_from_rt(int *x, int *y, int r, int t){
*x = (int)((float)r * cos(t)) + var_info.xres / 2;
*y = (int)((float)r * sin(t)) + var_info.yres / 2;
}
static void get_pixel_color(int x, int y, int *r, int *g, int *b){
//static void get_rt_from_xy(int *r, int *t, int x, int y){
// *r = sqrt(x*x + y*y);
// *t = asin(y/x);
//}
static void calculate_radii_table(){
for(int i = 0; i < NUM_LEDS_PER_WING; i++){ // This too will have to be different for staggered.
radii[i] = i * LED_SPACING + FAN_BLIND_ZONE_R;
}
}
fb_pixel fb[FRAME_BUFFER_SIZE];
volatile led_wing wings[NUM_WINGS] = { 0 };
static void calculate_index_table(){
int x, y;
for(int *r = radii; r < radii + NUM_LEDS_PER_WING; r++){ // This will have to be different for staggered leds/wings.
for(int t = 0; t < THETA_RESOLUTION; t++){
get_xy_from_rt(&x, &y, *r, t);
indices[r - radii][t] = x % var_info.xres + y * (x / var_info.xres);
}
}
}
static void get_pixel_color(int fb_index, int *r, int *g, int *b){
if(fb_index < var_info.xres * var_info.yres){
//printf("x: %d, y: %d\n", x, y);
//fb_pixel *p = &fb[x % var_info.xres + y * (x / var_info.xres)];
fb_pixel *p = &fb[fb_index];
*r = p->r;
*g = p->g;
*b = p->b;
}
}
static int update_out_buf(){
int fb_index;
int red, green, blue;
int r, wt;
for(size_t t = 0; t < THETA_RESOLUTION; t++){
for(size_t w = 0; w < NUM_WINGS; w++){
for(size_t l = 0; l < NUM_LEDS_PER_WING; l++){
int x, y;
int r, t;
int red, green, blue;
r = l * LED_SPACING + FAN_BLIND_ZONE_R;
t = (int)(((2.0*M_PI) / NUM_WINGS) * w) + t;
get_xy_from_rt(&x, &y, r, t);
get_pixel_color(x, y, &red, &green, &blue);
wt = ((int)(((THETA_RESOLUTION) / NUM_WINGS) * w) + t) % THETA_RESOLUTION;
fb_index = indices[l][wt];
get_pixel_color(fb_index, &red, &green, &blue);
set_wing_led_color(&wings[w], l, red, green, blue);
}
......@@ -94,11 +132,94 @@ size_t get_pov_buffer_size(){
return sizeof(wings);
}
static int get_fbfd(){
int fbfd = open("/dev/fb0", O_RDONLY);
if (fbfd < 0) {
printf("ERROR: Failed to open fb-dev.\n");
}
return fbfd;
}
static int update_fb(){
int fbfd = get_fbfd();
char *fbp = (char *) mmap(
NULL, fixed_info.smem_len, PROT_READ,
MAP_SHARED, fbfd, 0
);
if((int)fbp == -1){
printf("ERROR: Failed to map fb to user memory.\nERR: %d\n", errno);
}
else {
memcpy(fb, fbp, FRAME_BUFFER_SIZE);
}
munmap(fbp, fixed_info.smem_len);
close(fbfd);
return 0;
}
static int pov_close(){
int fbfd = get_fbfd();
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo)) {
printf("Error re-setting variable information.\n");
}
close(fbfd);
}
int pov_init(){
int fbfd = get_fbfd();
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var_info)) {
printf("EERROR: Failed to get variable display information.\n");
return -1;
}
printf("Orig display-info %dx%d, %d bpp\n",
var_info.xres, var_info.yres,
var_info.bits_per_pixel );
memcpy(&orig_vinfo, &var_info, sizeof(struct fb_var_screeninfo)); // Copy original settings for later.
// Change variable info
var_info.bits_per_pixel = POV_SCREEN_BPP;
var_info.xres = POV_SCREEN_WIDTH;
var_info.yres = POV_SCREEN_HEIGHT;
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var_info)) {
printf("ERROR: Failed to set display settings.\n");
}
printf("New display-info %dx%d, %d bpp\n",
var_info.xres, var_info.yres,
var_info.bits_per_pixel );
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fixed_info)) {
printf("ERROR: Failed to get fixed display information.\n");
}
// close file
close(fbfd);
calculate_radii_table();
calculate_index_table();
return 0;
}
void *pov_run(){
int err;
while(true){
while(true){
int msec = 0, trigger = 10; /* 10ms */
clock_t before = clock();
int cnt = 0;
while(cnt++ < 30000){
err = update_fb();
if(err){
goto pov_cleanup;
......@@ -108,9 +229,16 @@ void *pov_run(){
if(err){
goto pov_cleanup;
}
clock_t difference = clock() - before;
msec = difference * 1000 / CLOCKS_PER_SEC;
}
printf("Time taken %d seconds %d milliseconds (%d iterations)\n",
msec/1000, msec%1000, cnt);
pov_cleanup:
pov_close();
return NULL;
}
......
#define NUM_LEDS_PER_WING 64
#define NUM_WINGS 5
#define FRAME_BUFFER_SIZE 320*480
#define LED_SPACING 1
#define FAN_BLIND_ZONE_R 8
#define THETA_RESOLUTION 3000 // This should be set to something sort of reasonable.
#define LED_SPACING 1 // Number of fb-pixels between each led.
#define FAN_BLIND_ZONE_R 8 // Number of led-pixels in fan blind zone.
#define THETA_RESOLUTION 300 // This should be set to something sort of reasonable.
#define POV_BUFFER_TYPE const volatile char
#define POV_SCREEN_WIDTH 800
#define POV_SCREEN_HEIGHT 600
#define POV_SCREEN_BPP 8
typedef struct _fb_pixel{
uint8_t r;
......@@ -27,4 +30,5 @@ typedef struct _led_wing{
void *pov_run();
POV_BUFFER_TYPE *get_pov_buffer();
size_t get_pov_buffer_size();
\ No newline at end of file
size_t get_pov_buffer_size();
int pov_init();
\ No newline at end of file
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