/* * particlesim.c * * Authors: Francisco Fabregat, Anthony Hermez * Modified: May 3, 2024 */ #include #include #include #include #include #include #include #include #include #include #include #include #define N_PARTICLES 1 #define X_MIN -100 #define X_MAX 100 #define Y_MIN -100 #define Y_MAX 100 #define Z_MIN -100 #define Z_MAX 100 #define vX_MIN -5 #define vX_MAX 5 #define vY_MIN -5 #define vY_MAX 5 #define vZ_MIN -5 #define vZ_MAX 5 #define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1) #define REGS_BASE_REGISTER 0xb0000000 struct particle { float x, y, z; float x_v, y_v, z_v; }; typedef struct particle Particle; void clearScreen(void); void printGraph(void); void initialSetup(void); unsigned int* regAddr(int reg); void readData(void); void scaleData(Particle *particle); void printParticles(void); void clearBoard(void); void start(void); void stop(void); void signalHandler(int _); Particle particles[N_PARTICLES]; struct winsize w; char* lineTemp; char* board; int n_rows, n_cols; int fd; unsigned int *regs; float *data; int main(int argc, char * argv[]) { clearScreen(); ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); signal(SIGINT, signalHandler); n_rows = w.ws_row - 2; n_cols = w.ws_col + 2; char lineTemplate[n_rows][n_cols]; char boardArr[n_rows][n_cols]; for (int r = 0; r < n_rows; r++) { for (int c = 0; c < (n_cols - 2); c++) { lineTemplate[r][c] = ' '; } lineTemplate[r][n_cols - 2] = '\n'; lineTemplate[r][n_cols - 1] = 0; } lineTemp = lineTemplate; board = boardArr; fd = open("/dev/mem", O_RDWR|O_SYNC); if(fd == -1) { printf("Unable to open /dev/mem. Ensure it exists (major=1, minor=1)\n"); return -1; } regs = (unsigned int *)mmap(NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, REGS_BASE_REGISTER & ~MAP_MASK); stop(); initialSetup(); start(); while (1) { printGraph(); clearBoard(); //usleep(33333); usleep(300000); readData(); clearScreen(); } } void clearScreen(void) { printf("\e[1;1H\e[2J"); fflush(stdout); } void clearBoard(void) { memcpy(board, lineTemp, n_cols*n_rows); } void printGraph(void) { printf("\033[47m\033[30m"); for (int i = 0; i < n_rows; i++) { char* temp = board + (n_cols * i); printf("%s",temp); } printf("\033[0m\n"); } void plotParticle(Particle *particle) { scaleData(particle); int x_coord = ((n_cols - 2) * ((int)particle->x - X_MIN)) / (X_MAX - X_MIN); int y_coord = (n_rows * ((int)particle->y - Y_MIN)) / (Y_MAX - Y_MIN); int index = ((n_rows - y_coord) * n_cols) + x_coord; if (particle->z_v <= 0) { board[index] = '*'; } else { board[index] = '~'; } } void initialSetup(void) { clearBoard(); srand(time(0)); for (int i = 0; i < N_PARTICLES; i++) { volatile float *addr = regAddr((i*6) + 3); particles[i].x = (float) (rand() % ((X_MAX/2) + 1 - (X_MIN/2)) + (X_MIN/2)); particles[i].y = (float) (rand() % ((Y_MAX/2) + 1 - (Y_MIN/2)) + (Y_MIN/2)); particles[i].z = (float) (rand() % ((Z_MAX/2) + 1 - (Z_MIN/2)) + (Z_MIN/2)); particles[i].x_v = (float) (rand() % (vX_MAX + 1 - vX_MIN) + vX_MIN); particles[i].y_v = (float) (rand() % (vY_MAX + 1 - vY_MIN) + vY_MIN); particles[i].z_v = (float) (rand() % (vZ_MAX + 1 - vZ_MIN) + vZ_MIN); addr[0] = particles[i].x; addr[1] = particles[i].y; addr[2] = particles[i].z; addr[3] = particles[i].x_v; addr[4] = particles[i].y_v; addr[5] = particles[i].z_v; plotParticle(&particles[i]); } unsigned int *dtAddr = regAddr(0); unsigned int *cAddr = regAddr(1); *dtAddr = 0x3727c5ac; //current value: 0.00001 *cAddr = 0x3a83126f; //current value: 0.001 } void readData(void) { for (int i = 0; i < N_PARTICLES; i++) { volatile float *addr = regAddr((i*3) + 9); particles[i].x_v = addr[0] - particles[i].x; particles[i].y_v = addr[1] - particles[i].y; particles[i].z_v = addr[2] - particles[i].z; particles[i].x = addr[0]; particles[i].y = addr[1]; particles[i].z = addr[2]; plotParticle(&particles[i]); } } void scaleData(Particle *particle) { if(particle->x < X_MIN || particle->x > X_MAX) { // reposition x in a random spot relative to itself (temp fix to overflow bug) particle->x = (float) (rand() % ((X_MAX/2) + 1 - (X_MIN/2)) + (X_MIN/2)); particle->x_v = (float) (rand() % (vX_MAX + 1 - vX_MIN) + vX_MIN); } if(particle->y < Y_MIN || particle->y > Y_MAX) { // reposition y in a random spot relative to itself (temp fix to overflow bug) particle->y = (float) (rand() % ((Y_MAX/2) + 1 - (Y_MIN/2)) + (Y_MIN/2)); particle->y_v = (float) (rand() % (vY_MAX + 1 - vY_MIN) + vY_MIN); } if(particle->z < Z_MIN || particle->z > Z_MAX) { // reposition z in a random spot relative to itself (temp fix to overflow bug) particle->z = (float) (rand() % ((Z_MAX/2) + 1 - (Z_MIN/2)) + (Z_MIN/2)); particle->z_v = (float) (rand() % (vZ_MAX + 1 - vZ_MIN) + vZ_MIN); } } void printParticles(void) { for (int i = 0; i < N_PARTICLES; i++) { printf("%d:\n\tX:%f\n\tY:%f\n\tZ:%f\n\tvX:%f\n\tvY:%f\n\tvZ:%f\n", i, particles[i].x, particles[i].y, particles[i].z, particles[i].x_v, particles[i].y_v, particles[i].z_v); } } void start(void) { unsigned int *addr = regAddr(2); *addr = 1; } void stop(void) { unsigned int *addr = regAddr(2); *addr = 0; } unsigned int* regAddr(int reg) { return regs + (((REGS_BASE_REGISTER + (reg * 4)) & MAP_MASK)>>2); } void signalHandler(int _) { stop(); clearScreen(); printf("Finished Simulation\n"); // Close memory int temp = close(fd); if(temp == -1) { printf("Unable to close /dev/mem. Ensure it exists (major=1, minor=1)\n"); } munmap(NULL, MAP_SIZE); exit(0); }