Skip to content

Instantly share code, notes, and snippets.

@KGrzeg
Last active June 2, 2020 00:14
Show Gist options
  • Select an option

  • Save KGrzeg/07c4053d6a679388ea9691e3c39731a7 to your computer and use it in GitHub Desktop.

Select an option

Save KGrzeg/07c4053d6a679388ea9691e3c39731a7 to your computer and use it in GitHub Desktop.
#include <Atmel/AT89X52.h>
#include <absacc.h>
#include <stdio.h>
#include "LCD_lib.c"
#define CS55A 0xFF28 // write
#define CS55B 0xFF29 // read
#define CS55D 0xFF2B // setup
#define CSKB0 0xF021
#define CSKB1 0xF022
#define INTERVAL 1000
#define MAX_PEOPLE 50
typedef enum { false, true } bool;
char text_max[] = "Brak wolnych\nmiejsc", text[] = "Osoby: \n";
struct {
unsigned char occupied;
unsigned char max;
unsigned char input_gates;
unsigned char output_gates;
} gates_data;
void lcd_print(const char *str) {
unsigned char i = 0;
while (str[i])
lcd(str[i++]);
}
void lcd_print_number(int num) {
char digits[3] = {0};
sprintf(digits, "%d", num);
lcd_print(digits);
}
bool reach_max() { return gates_data.max <= gates_data.occupied; }
bool empty() { return gates_data.occupied == 0; }
void setup_input_gate(unsigned char id) { gates_data.input_gates |= 1 << id; }
void setup_input_gates_raw(unsigned char d) { gates_data.input_gates |= d; }
void reset_input_gates() { gates_data.input_gates = 0; }
void setup_output_gate(unsigned char id) { gates_data.output_gates |= 1 << id; }
void setup_output_gates_raw(unsigned char d) { gates_data.output_gates |= d; }
void reset_output_gates() { gates_data.output_gates = 0; }
void initialize_gates() {
gates_data.max = MAX_PEOPLE;
gates_data.occupied = 0;
reset_input_gates();
reset_output_gates();
XBYTE[CS55D] = 0x82;
lcd_init();
lcd_clr();
}
void display_status() {
if (reach_max()) {
lcd_print(text_max);
} else {
lcd_print(text);
lcd_print_number(gates_data.occupied);
lcd('/');
lcd_print_number(gates_data.max);
}
}
void add_person() { gates_data.occupied += reach_max() ? 0 : 1; }
void sub_person() { gates_data.occupied -= empty() ? 0 : 1; }
unsigned int count_high_bits(unsigned int n) {
unsigned int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
unsigned char detect_rises(char last, char current) {
char result = (last ^ current) & current;
return count_high_bits(result);
}
void update_system() {
static unsigned char last_input_state = 0, last_output_state = 0;
unsigned char input_state, output_state, people, current_state;
current_state = XBYTE[CS55B];
// check in gates
input_state = current_state & gates_data.input_gates;
people = detect_rises(last_input_state, input_state);
while (people--) {
add_person();
}
// check out gates
output_state = current_state & gates_data.output_gates;
people = detect_rises(last_output_state, output_state);
while (people--) {
sub_person();
}
last_input_state = input_state;
last_output_state = output_state;
}
void live_setup() {
unsigned char nums, status;
nums = ~XBYTE[CSKB0];
status = ~XBYTE[CSKB1];
switch (status) {
case 0: {
return;
break;
}
case 128: { //'F' - reset amount of people
gates_data.occupied = 0;
break;
}
case 4: { // A - input gates
setup_input_gates_raw(nums);
break;
}
case 8: { // B - output gates
setup_output_gates_raw(nums);
break;
}
case (16 + 4): { // C+A - reset input gates
reset_input_gates();
break;
}
case (16 + 8): { // C+B - reset output gates
reset_output_gates();
break;
}
}
}
void main() {
initialize_gates();
setup_output_gate(0);
setup_output_gate(1);
setup_output_gate(2);
setup_output_gate(3);
setup_input_gate(4);
setup_input_gate(5);
setup_input_gate(6);
while (1) {
P1_7 = 0;
wait(80);
P1_7 = 1;
update_system();
live_setup();
display_status();
wait(INTERVAL);
lcd_clr();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment