source: projects/punch-card/driver/documation-m200/src/io.c @ 50

Last change on this file since 50 was 50, checked in by sven, 10 years ago
  • The PC Documation M200 uC Serial Communication Protocol: Initial write
  • driver/documation-m200: Implemented the protocol (code compiles, but not tested yet on device)

-- Sven @ p3

File size: 6.4 KB
Line 
1/**
2 * Input/Output routines
3 * and the whole protocol implementation
4 *
5 **/
6
7#include <stdio.h>
8#include <avr/pgmspace.h> // for all the strings
9
10#include "io.h"
11#include "punchcard.h"
12#include "wiring.h"
13
14// declare some global static string messages
15char help_message[] PROGMEM =
16        M200_SERVER_HELP " HELP\n"
17        M200_SERVER_HELP " ====\n"
18        M200_SERVER_HELP "\n"
19        M200_SERVER_HELP " This is the AVR M200 Card Reader Controller RS232 interface\n"
20        M200_SERVER_HELP " The communication is standarized by the\n"
21        M200_SERVER_HELP "     PC Documation M200 uC Serial Communication Protocol\n"
22        M200_SERVER_HELP " Please see that document for further help on syntax and commands.\n"
23        M200_SERVER_HELP "\n"
24        M200_SERVER_HELP " Available Request codes\n"
25        M200_SERVER_HELP " (simply type into, without any trailing ENTER):\n"
26        M200_SERVER_HELP "\n"
27        M200_SERVER_HELP "    h    Prints out this help message\n"
28        M200_SERVER_HELP "    c    Connect: Give out Version and reset, waiting for request\n"
29        M200_SERVER_HELP "    0    Ping: Make me answer something as soon as possible\n"
30        M200_SERVER_HELP "    1    Start punching as soon as possible\n"
31        M200_SERVER_HELP "    2    Stop punching as soon as possible\n"
32        M200_SERVER_HELP "    3    Set output to hexadecimal output (that is, ASCII output)\n"
33        M200_SERVER_HELP "    4    Set output to debug output (very verbose ASCII output)\n"
34        M200_SERVER_HELP "    5    Set output to binary output (you don't want to do that in a terminal)\n"
35        M200_SERVER_HELP "    6    Reset internal buffers, stop punching (same as c...)\n"
36        M200_SERVER_HELP "\n";
37
38
39void print_startup_message() {
40        printf(M200_SERVER_STARTUP " v%d.%d Welcome to the M200 Punch Card Reader Microcontroller\n",
41                M200_PROTOCOL_VERSION_MAJOR, M200_PROTOCOL_VERSION_MINOR);
42        puts(M200_SERVER_HELP " type 'h' for help.");
43}
44
45// Haupt-Transmit-Routine, backend von stdio
46int uart_transmit(char c, FILE* stream) {
47        if(c == '\n')
48                uart_transmit('\r', stream);
49
50        while (!(UCSR0A & 0b00100000));
51        // PENDING: Hardware flow control
52        UDR0 = c;
53        return 0;
54}
55
56unsigned char uart_recieve() {
57        if(UCSR0A & 0b10000000) // if RXC(Bit 7) == 1
58                return UDR0;
59        else
60                return NO_INPUT;
61}
62
63void print_bits(byte_t byte) {
64        char str[10];
65        byte_t bit; byte_t pos = 0;
66        for(bit = 7; bit >= 0; bit--) {
67                str[pos++] = ( (1 << bit) & byte ) ? '1' : '0';
68        }
69        str[8] = ' ';
70        str[9] = '\0';
71
72        puts(str);
73}
74
75void print_card(enum format_t out_format) {
76        switch(out_format) {
77                case HEX:
78                        for(uint8_t col = 0; col < CARD_LEN; col++) {
79                                printf(M200_SERVER_HEX_PREFIX "%02d 0x%x 0x%x\n", col,
80                                        (uint8_t) (current_read_card.columns[col] >> 8),
81                                        (uint8_t) (current_read_card.columns[col])
82                                );
83                        }
84                        break;
85                case DEBUG:
86                        for(uint8_t col = 0; col < CARD_LEN; col++) {
87                                printf(M200_SERVER_DEBUG_PREFIX "%02d ", col);
88                                column_print( &current_read_card.columns[col] );
89                                puts(""); // newline?
90                        }
91                        break;
92                case BINARY:
93                        puts(M200_SERVER_BINARY " BINARY");
94                        {
95                                // make two columns to three bytes, after Douglas Jones
96                                uint8_t x = 0;
97                                Column even_col, odd_col;
98                                while(x <= CARD_LEN) {
99                                        even_col = current_read_card.columns[x++];
100                                        odd_col = current_read_card.columns[x++];
101
102                                        putchar( even_col >> 4 ); // erstes byte
103                                        putchar( ((even_col & 017) << 4) | (odd_col >> 8) ); // zweites byte
104                                        putchar( odd_col & 00377 ); // drittes byte
105                                }
106                        }
107                        puts(M200_SERVER_BINARY_PREFIX "08 FINISHED");
108                        break;
109                default:
110                        puts("550 Illegal Format at runtime");
111        } // switch out_format
112}
113
114void user_input_loop() {
115        enum format_t out_format = DEBUG;
116        unsigned char input = NO_INPUT;
117
118        print_startup_message();
119
120        while(1) {
121                input = uart_recieve();
122                if(input != NO_INPUT) {
123                        // there is user input
124                        switch(input) {
125                                case M200_CLIENT_HELP:
126                                        // print out very long help message
127                                        puts_P(help_message);
128                                        break;
129                                case M200_CLIENT_PING:
130                                        // print out some ping pong thingy
131                                        puts(M200_SERVER_PONG " Pong");
132                                        break;
133                                case M200_CLIENT_START:
134                                        status.user_instruction = START_READER;
135                                        start_reader();
136                                        start_led();
137                                        break;
138                                case M200_CLIENT_STOP:
139                                        status.user_instruction = STOP_READER;
140                                        stop_reader();
141                                        stop_led();
142                                        break;
143                                case M200_CLIENT_HEX:
144                                case M200_CLIENT_DEBUG:
145                                case M200_CLIENT_BINARY:
146                                        if(!is_valid_format(input)) {
147                                                printf(M200_SERVER_ILLEGAL_FORMAT " Illegal format ''%c'! Type `h` for valid formats\n", input);
148                                                break;
149                                        }
150                                        out_format = input;
151                                        printf(M200_SERVER_ACK_PREFIX "%c input format set okay\n", out_format);
152
153                                case M200_CLIENT_RESET:
154                                        status.user_instruction = STOP_READER;
155                                        stop_reader();
156                                        stop_led();
157                                        card_buffer_flush();
158                                        puts(M200_SERVER_ACK_RESET " Resetted instruction storage, pins, cycle memory");
159                                        print_startup_message();
160                                        break;
161                                default:
162                                        printf(M200_SERVER_ILLEGAL_COMMAND " Illegal command '%c'! Type `h` for valid commands\n", input);
163                        } // switch
164                } // if user input
165
166                // after handling user input, handle buffer
167                if( current_read_card.offset == CARD_READY ) {
168                        printf("Karte in rd %d rw %d, cols rd %d rw %d\n", card_buffer.read_offset, card_buffer.write_offset,
169                                current_read_card.offset, current_write_card.offset);
170
171                        // Karte abgearbeitet-Dingens war vorher hier (...=CARD_DONE).
172                        // das war nicht gut.
173
174                        //break; // Karte NICHT komplett ausgeben. Hier stoppen.
175
176                        print_card(out_format);
177
178
179                        // Karte abgearbeitet
180                        current_read_card.offset = CARD_DONE;
181
182                } // karte liegt vor
183
184                if( current_read_card.offset == CARD_DONE) {
185                        // alle karten abgearbeitet, versuche zur naechsten
186                        // Karte zu kommen
187                        if( card_buffer_read_advance() != SUCCESS) {
188                                puts("output waiting for next");
189                        } else {
190                                puts("cr+");
191                        }
192
193                        // und der Writer kann jetzt auch wieder loslegen
194                        // also eigentlich wartet hier ja der WRITER
195                        if(status.reader_waits_for_space) {
196                                // leser hat auf uns gewartet (puffer war voll, leser war angehalten,
197                                // wir haben nun eine weitere Karte gelesen => Leser kann in dieses
198                                // Feld nun wieder schreiben)
199                                if(card_buffer_write_advance() == SUCCESS) {
200                                        // es kann wieder weitergehen fuer den Leser
201                                        status.reader_waits_for_space = 0;
202                                        start_reader();
203                                } else {
204                                        puts("Deadline, writer waits for reader");
205                                }
206                        }
207                } // aktuelle Karte abgearbeitet
208        } // while 1
209} // function
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License