Difference between revisions of "Dual Display station - software description"
From Zenitel Wiki
(→UART1 console commands) |
(→Stack dump) |
||
(8 intermediate revisions by 4 users not shown) | |||
Line 212: | Line 212: | ||
|width="100pt" |<main.c> | |width="100pt" |<main.c> | ||
|- | |- | ||
− | |Entry functions: <br | + | |Entry functions: <br />|| digit_process()<br />put_digit_in_buffer() |
|- | |- | ||
|} | |} | ||
Line 253: | Line 253: | ||
:* PB6 (MP): M-key current | :* PB6 (MP): M-key current | ||
:* PB5 (ONH): Handset ON current | :* PB5 (ONH): Handset ON current | ||
− | In idle, the station signals "Handset ON" current (13mA). By pressing M- or C-key, or by lifting the handset, the current is changed accordingly. In software, this is indicated to <br | + | In idle, the station signals "Handset ON" current (13mA). By pressing M- or C-key, or by lifting the handset, the current is changed accordingly. In software, this is indicated to <br />"digit_process()" by the status flags "status.hsoff", "status.mkey" and "status.ckey", and does not require a key code to be processed through the key code buffer (see below). |
Only one of the current levels may be signalled at a time, except short periods during transitions between current levels. Because there are several inputs specifying the current level, the final value is determined by the following priority: | Only one of the current levels may be signalled at a time, except short periods during transitions between current levels. Because there are several inputs specifying the current level, the final value is determined by the following priority: | ||
Line 269: | Line 269: | ||
{| border="1" | {| border="1" | ||
|- | |- | ||
− | !style="background:#ffdead;" width="100pt"|Frequency:<br | + | !style="background:#ffdead;" width="100pt"|Frequency:<br />(C-D wires) |
− | !style="background:#ffdead;" width="100pt"|Current:<br | + | !style="background:#ffdead;" width="100pt"|Current:<br />(A-B wires) |
!style="background:#ffdead;" width="100pt"|Key code: | !style="background:#ffdead;" width="100pt"|Key code: | ||
!style="background:#ffdead;" width="100pt"|Key | !style="background:#ffdead;" width="100pt"|Key | ||
Line 526: | Line 526: | ||
|0x33 (modified) || Multiple display version of command 0x03. Display address is first byte after command. Supported addresses: 0x00 = main display, 0x01 = DAK display. For DAK display: Control code 0x13 is line number, not cursor position. Other control codes not supported. | |0x33 (modified) || Multiple display version of command 0x03. Display address is first byte after command. Supported addresses: 0x00 = main display, 0x01 = DAK display. For DAK display: Control code 0x13 is line number, not cursor position. Other control codes not supported. | ||
|- | |- | ||
− | |0x41 (modified) <br | + | |0x41 (modified) <br /><br /><br /><br /><br /><br /><br /><br /><br /><br />|| Set indicator status command; will set status on one indicator as off, on, slow blink or fast blink. |
It will refer to KEY number (K), indicator number (I) and status selector with state (S). Many indicator can be set with one command: | It will refer to KEY number (K), indicator number (I) and status selector with state (S). Many indicator can be set with one command: | ||
Example: 0x41+ KIS+KIS+....+KIS+ checksum (up to 9 KIS) | Example: 0x41+ KIS+KIS+....+KIS+ checksum (up to 9 KIS) | ||
Line 631: | Line 631: | ||
Located in file: <debug.c> | Located in file: <debug.c> | ||
− | To simplify software debugging several debug-specific functions have been made. All debug code is optionally included during compilation by selecting "#define" statements in the file <main.h>. All debug functions can be removed by deselecting "#define <br | + | To simplify software debugging several debug-specific functions have been made. All debug code is optionally included during compilation by selecting "#define" statements in the file <main.h>. All debug functions can be removed by deselecting "#define <br />DEBUG_ENABLED". |
The different functions are listed below. | The different functions are listed below. | ||
Line 685: | Line 685: | ||
This function enables command messages to be received by UART1 Rx from terminal/PC. The messages are received as normal ASCII text, and are used to execute operations or dump status in the station. | This function enables command messages to be received by UART1 Rx from terminal/PC. The messages are received as normal ASCII text, and are used to execute operations or dump status in the station. | ||
− | List of UART1 debug command messages:<br | + | List of UART1 debug command messages:<br /> |
(Note: Some commands expect <enter> to be pressed after typing, others are executed on-the-fly when the command byte is received. All commands are case-sensitive.) | (Note: Some commands expect <enter> to be pressed after typing, others are executed on-the-fly when the command byte is received. All commands are case-sensitive.) | ||
Line 749: | Line 749: | ||
==== Stack dump ==== | ==== Stack dump ==== | ||
+ | |||
{| | {| | ||
|- | |- | ||
− | + | |width="90pt" |Controlled by: | |
− | + | |width="90pt" |#define DEBUG_TEST_STACK | |
|- | |- | ||
|Required code space: || Approx. 400 bytes. | |Required code space: || Approx. 400 bytes. | ||
Line 759: | Line 760: | ||
|- | |- | ||
|} | |} | ||
− | This option is for dumping stack location and contents during startup. Studying the stack may be helpful when the program seems to crash for no reason. Normally this function is not needed. Dumping the stack contents will exceed | + | This option is for dumping stack location and contents during startup. Studying the stack may be helpful when the program seems to crash for no reason. Normally this function is not needed. Dumping the stack contents will exceed the Tx1 buffer of 70 bytes and cause the processor to be occupied for some time. |
+ | |||
+ | [[Category: Analogue Station - Technical articles]] |
Latest revision as of 13:14, 1 November 2016
Contents
Coding conventions
Software configuration: Using #define settings
By setting or removing #define precompiler statements, pieces of code can be easily added or removed. One example of this is enabling or disabling all debug functionality in a release:
- #define DEBUG_ENABLED
All such statements are collected in the top of the file <main.h>.
Loading C strings from FLASH
The IAR C compiler for AVR processors is by default configured for reading strings from DATA segment (RAM). This requires the compiler to copy the strings from FLASH to RAM during initialisation/cstartup. After that, the stings can be used in normal "ANSI C style":
- printf("Hello World!");
Loading the strings to RAM is required for the strings to be manipulated during run-time. But by using special-designed functions instead of printf(), this can be avoided. Printing strings is done with a separate function, which loads text from FLASH only.
This could be achieved by pre-defining all strings:
- BYTE flash *string_example = "Hello World!";
... and it would be used this way:
- print_string(string_example);
This is not an easy code to read. Instead, the string could be used the normal way by making a few configurations:
- The CSTR segment containing strings is configured as a CODE segment (FLASH) in the linker file <lnk3s4kb_MODIFIED.xcl>.
- The function using the strings must cast the pointer from RAM to FLASH type. This is because the pointer is actually pointing at the correct address in FLASH, but the compiler still believes it is a RAM pointer. For example:
void print_string(BYTE *string_temp)
- {
- BYTE flash *string;
- string = (BYTE flash *)(WORD)string_temp;
- ...
- }
"string_temp" is an invalid RAM pointer, but the FLASH pointer "string" can now be used normally instead.
- In some cases, pre-defined strings are preferred if a string is used multiple times. But now the problem is vice versa: The function is expecting a RAM pointer, but the pointer is in this case actually FLASH. So we have to cast the pointer to RAM to be able to compile the code:
BYTE flash *string_example = "Hello World!"; print_string( (BYTE *)(WORD)string_example );
Code description
General program structure
After initialisation, the program enters an infinite loop in which all processes are executed. Some processes are executed every 10ms, while others run continuously.
To generate the 10ms intervals, TIMER0 interrupt is used. It increments a counter by 1 every 10ms. The main loop checks this counter, and executes the required processes if it is greater than 0. Also, the counter is decremented by 1.
The process states and timers are kept within the separate processes, and no high-level FSM is used. Global status flags are held in a bit-struct register "status".
Keyboard scanning
Located in file: | <main.c> |
Entry function: | scan_matrix_keyboard() |
Hardware
The station keyboard is an 8x4 matrix connected to PB1-PD3 (outputs) and PD4-PD7 (inputs).
Debounce routine
For each of the 32 keys there is a debounce register of 8 bits:
Key status: | 1 bit |
Key counter up: | 3 bits |
Key counter down: | 4 bits |
The keyboard scanning process is executed by 10ms intervals. For a keypress to be accepted, the key must be held for a specified amount of 10ms counts, counted by the up-counter. The key code is then sent to the AlphaCom digit sending process. Similarly, a key release also requires the key to be released for some time, counted by the down-counter. The key code 0x80 is then sent, telling the digit process to stop sending.
Key codes
The 32 keys are mapped this way:
Position | Key name: | Key code: (1) | Comment |
---|---|---|---|
COL1, ROW1 | KEY_1 | 0x01 | |
COL1, ROW2 | KEY_2 | 0x02 | |
COL1, ROW3 | KEY_3 | 0x03 | |
COL1, ROW4 | KEY_MENU | 0x2a | DAK 20 |
COL2, ROW1 | KEY_4 | 0x04 | |
COL2, ROW2 | KEY_5 | 0x05 | |
COL2, ROW3 | KEY_6 | 0x06 | |
COL2, ROW4 | KEY_UPARROW | 0x2b | DAK 21 |
COL3, ROW1 | KEY_7 | 0x07 | |
COL3, ROW2 | KEY_8 | 0x08 | |
COL3, ROW3 | KEY_9 | 0x09 | |
COL3, ROW4 | KEY_DOWNARROW | 0x2c | DAK 22 |
COL4, ROW1 | KEY_M | 0x35 | (2) |
COL4, ROW2 | KEY_0 | 0x0a | |
COL4, ROW3 | KEY_C | 0x5f | (3) |
COL4, ROW4 | KEY_NAME | 0x2d | DAK 23 |
COL5, ROW1 | KEY_DAK1 | Key codes depend on which DAK page is currently displayed. (4) | |
COL5, ROW2 | KEY_DAK2 | " | |
COL5, ROW3 | KEY_DAK3 | " | |
COL5, ROW4 | KEY_DAK4 | " | |
COL6, ROW1 | KEY_DAK5 | " | |
COL6, ROW2 | KEY_DAK6 | " | |
COL6, ROW3 | KEY_DAK7 | " | |
COL6, ROW4 | KEY_DAK8 | " | |
COL7, ROW1 | KEY_DAK9 | " | |
COL7, ROW2 | KEY_DAK10 | " | |
COL7, ROW3 | |||
COL7, ROW4 | KEY_PRIVACY | (No code) | Other signalling. |
COL8, ROW1 | |||
COL8, ROW2 | |||
COL8, ROW3 | |||
COL8, ROW4 |
(1): For the complete list of key codes and their signalling, see chapter [4.3 AlphaCom digit sending].
(2): The M-key code is not sent upon keypress. Instead, the global status "status.mkey" is set. Handset M-key will also set "status.mkey" when pressed.
(3): The C-key code is not sent upon keypress. Instead, the global status "status.ckey" is set.
(4): The DAK key codes depend on which DAK page is currently displayed on the upper LCD. There are 50 DAK key codes available, and by adding a prefix code (0x74) this amount is doubled. The key codes are according to the CRM IV station standard, which defines the following table:
DAK page displayed: | DAK keys: | Key codes: | Comment |
---|---|---|---|
0 | D0-D9 | 0x20-0x29 | |
1 | D10-D19 | 0x0a-0x13 | |
2 | D20-D29 | 0x2a-0x33 | Menu keys |
3 | D30-D39 | 0x60-0x69 | |
4 | D40-D49 | 0x6a-0x73 | |
5 | D50-D59 | (0x74+) 0x20-0x29 | |
6 | D60-D69 | (0x74+) 0x0a-0x13 | |
7 | D70-D79 | (0x74+) 0x2a-0x33 | |
8 | D80-D89 | (0x74+) 0x60-0x69 | |
9 | D90-D99 | (0x74+) 0x6a-0x73 |
Other input pins
There are some extra inputs that are also scanned by the keyboard process:
- PE2: C-D loop sense (conversation/station LED)
- PC1: Handset OFF
- PC0: Handset M-key
AlphaCom digit sending
Located in file: | <main.c> |
Entry functions: |
digit_process() put_digit_in_buffer() |
Digit transmission is processed by the function "digit_process()". The digits are sent by two signals:
- Tone frequencies
- * Sent on C-D wires (microphone). Polarity is inverted first.
- * Frequency range: 400Hz - 4000Hz.
- Current-signals
- * Sent on A-B wires (speaker).
- * Signal levels: (Note: The station itself consumes 10mA (1) at all times, which is included in the values below)
Handset OFF: 10mA (1) Handset ON: 13mA M-key: 24mA C-key: 50mA
(1): Due to high power consumption, the station is currently set to consume 13mA at all times. This is equal to "Handset ON" signal (13mA), and the "Handset OFF" signal (10mA) can never be signalled. This is configured in hardware, and does not affect the software.
Tone signalling (C-D wires)
Tones are transmitted through the following processor output pins:
- PE2 (TO): Tone frequency signal.
- PB4 (ID): ID signal. Set high when sending tone.
The ID pin is held high when sending a tone. The tone frequency is then set on the TO pin. When not sending a tone, the ID pin is low. The TO pin is then used for reflecting the privacy status of the station, determined by the flag "status.privacy": Low level means Open and high level means Private.
Current signalling (A-B wires)
A current-signal is always present on the A-B wires. The processor has three output lines controlling the current:
- PB7 (CP): C-key current
- PB6 (MP): M-key current
- PB5 (ONH): Handset ON current
In idle, the station signals "Handset ON" current (13mA). By pressing M- or C-key, or by lifting the handset, the current is changed accordingly. In software, this is indicated to
"digit_process()" by the status flags "status.hsoff", "status.mkey" and "status.ckey", and does not require a key code to be processed through the key code buffer (see below).
Only one of the current levels may be signalled at a time, except short periods during transitions between current levels. Because there are several inputs specifying the current level, the final value is determined by the following priority:
- 1. "status.ckey" flag
- 2. Current level specified by a key code - see "Key codes" below.
- 3. "status.mkey" flag
- 4. "status.hsoff" flag (station is in idle, with handset ON or OFF)
Key codes
Key codes are sent through a key code buffer by the function "put_digit_in_buffer()". This buffer is read by "digit_process()", which then sends both tone and current signals according to the key code. Digits will be held for a minimum time, and released when a new key code is available in the buffer. Key codes with the bit "0x80" set will stop the digit transmission.
AlphaCom line signalling:
Frequency: (C-D wires) |
Current: (A-B wires) |
Key code: | Key | Comment |
---|---|---|---|---|
500 Hz | (no change) | 0x00 | Digit 0 | |
700 Hz | (no change) | 0x01 | Digit 1 | |
900 Hz | (no change) | 0x02 | Digit 2 | |
1100 Hz | (no change) | 0x03 | Digit 3 | |
1300 Hz | (no change) | 0x04 | Digit 4 | |
1500 Hz | (no change) | 0x05 | Digit 5 | |
1700 Hz | (no change) | 0x06 | Digit 6 | |
1900 Hz | (no change) | 0x07 | Digit 7 | The current-signal is not affected by the key code.
In station idle it will be "Handset ON". |
2100 Hz | (no change) | 0x08 | Digit 8 | " |
2300 Hz | (no change) | 0x09 | Digit 9 | " |
400 Hz | (no change) | 0x0a | DAK 10 | " |
2600 Hz | (no change) | 0x0b | DAK 11 | " |
450 Hz | (no change) | 0x0c | DAK 12 | " |
2900 Hz | (no change) | 0x0d | DAK 13 | " |
600 Hz | (no change) | 0x0e | DAK 14 | " |
3200 Hz | (no change) | 0x0f | DAK 15 | " |
800 Hz | (no change) | 0x10 | DAK 16 | " |
3600 Hz | (no change) | 0x11 | DAK 17 | " |
1000 Hz | (no change) | 0x12 | DAK 18 | " |
4000 Hz | (no change) | 0x13 | DAK 19 | " |
500 Hz | M-key | 0x20 | DAK 0 | |
700 Hz | M-key | 0x21 | DAK 1 | |
900 Hz | M-key | 0x22 | DAK 2 | |
1100 Hz | M-key | 0x23 | DAK 3 | |
1300 Hz | M-key | 0x24 | DAK 4 | |
1500 Hz | M-key | 0x25 | DAK 5 | |
1700 Hz | M-key | 0x26 | DAK 6 | |
1900 Hz | M-key | 0x27 | DAK 7 | |
2100 Hz | M-key | 0x28 | DAK 8 | |
2300 Hz | M-key | 0x29 | DAK 9 | |
400 Hz | M-key | 0x2a | DAK 20 | |
2600 Hz | M-key | 0x2b | DAK 21 | |
450 Hz | M-key | 0x2c | DAK 22 | |
2900 Hz | M-key | 0x2d | DAK 23 | |
600 Hz | M-key | 0x2e | DAK 24 | |
3200 Hz | M-key | 0x2f | DAK 25 | |
800 Hz | M-key | 0x30 | DAK 26 | |
3600 Hz | M-key | 0x31 | DAK 27 | |
1000 Hz | M-key | 0x32 | DAK 28 | |
4000 Hz | M-key | 0x33 | DAK 29 | |
500 Hz | Handset OFF | 0x40 | Digit 0 | The hardware does not support handset yet, and can only signal "Handset ON" current (13mA) or higher.
These key codes will be sent with "Handset ON" current instead. |
700 Hz | Handset OFF | 0x41 | Digit 1 | " |
900 Hz | Handset OFF | 0x42 | Digit 2 | " |
1100 Hz | Handset OFF | 0x43 | Digit 3 | " |
1300 Hz | Handset OFF | 0x44 | Digit 4 | " |
1500 Hz | Handset OFF | 0x45 | Digit 5 | " |
1700 Hz | Handset OFF | 0x46 | Digit 6 | " |
1900 Hz | Handset OFF | 0x47 | Digit 7 | " |
2100 Hz | Handset OFF | 0x48 | Digit 8 | " |
2300 Hz | Handset OFF | 0x49 | Digit 9 | " |
400 Hz | Handset OFF | 0x4a | " | |
2600 Hz | Handset OFF | 0x4b | " | |
450 Hz | Handset OFF | 0x4c | " | |
2900 Hz | Handset OFF | 0x4d | " | |
600 Hz | Handset OFF | 0x4e | " | |
3200 Hz | Handset OFF | 0x4f | " | |
800 Hz | Handset OFF | 0x50 | " | |
3600 Hz | Handset OFF | 0x51 | " | |
1000 Hz | Handset OFF | 0x52 | " | |
4000 Hz | Handset OFF | 0x53 | " | |
500 Hz | C-key | 0x60 | DAK 30 | |
700 Hz | C-key | 0x61 | DAK 31 | |
900 Hz | C-key | 0x62 | DAK 32 | |
1100 Hz | C-key | 0x63 | DAK 33 | |
1300 Hz | C-key | 0x64 | DAK 34 | |
1500 Hz | C-key | 0x65 | DAK 35 | |
1700 Hz | C-key | 0x66 | DAK 36 | |
1900 Hz | C-key | 0x67 | DAK 37 | |
2100 Hz | C-key | 0x68 | DAK 38 | |
2300 Hz | C-key | 0x69 | DAK 39 | |
400 Hz | C-key | 0x6a | DAK 40 | |
2600 Hz | C-key | 0x6b | DAK 41 | |
450 Hz | C-key | 0x6c | DAK 42 | |
2900 Hz | C-key | 0x6d | DAK 43 | |
600 Hz | C-key | 0x6e | DAK 44 | |
3200 Hz | C-key | 0x6f | DAK 45 | |
800 Hz | C-key | 0x70 | DAK 46 | |
3600 Hz | C-key | 0x71 | DAK 47 | |
1000 Hz | C-key | 0x72 | DAK 48 | |
4000 Hz | C-key | 0x73 | DAK 49 | |
(ID, but no freq) | M-key | 0x34 | Special purpose. | |
(ID, but no freq) | Handset ON | 0x14 | " | |
(ID, but no freq) | Handset OFF | 0x54 | " | |
(ID, but no freq) | C-key | 0x74 | " | |
M-key | 0x35 | M-key | ||
C-key | 0x5f | C-key |
AlphaCom display messages
Located in file: <main.c>
Similar to previous AlphaCom stations, display messages are received by the processor through UART interrupts. The messages are decoded with function "parse_message()".
Message commands for Master Station DualDisplay
Command | Description |
---|---|
0x01 (modified) | Display commands. Some commands for previous stations not supported. |
0x02 | Print bytes as display text or store as CGRAM data (character generator RAM). |
0x03 | Print bytes as display text or store as CGRAM data, but interpret values in the range 0x10-0x1f as control codes. |
0x04 | Load the main address register with the two first data bytes of message if the processor has received two pulses on the C-D loop sense pin within 700ms. This is a double flash in the station LED and the sequence on the C-D loop sense pin is 1-0-1-0-1. The first 1 must be present when the message is processed, meaning that the LED must be off. Most significant byte is first data byte. |
0x05 | Load the first data byte as the K-group address. |
0x06 | NOT SUPPORTED |
0x07 | NOT SUPPORTED |
0x08 | NOT SUPPORTED |
0x09 | Mask broadcast. Messages with address 0xfffe is ignored. |
0x0a | Unmask broadcast. Messages with address 0xfffe is recognised. |
0x0b | NOT SUPPORTED |
0x0c | NOT SUPPORTED |
0x0d | NOT SUPPORTED |
0x0e | NOT SUPPORTED |
0x20 | NOT SUPPORTED |
0x21 | NOT SUPPORTED |
0x22 | Use the data bytes in message as digit codes, and send them on the CD and AB wires. |
0x23 | Activate handset and volume override. |
0x24 | Deactivate handset and volume override. |
0x25 | Load the main address register with the two first data bytes of the message without looking for any pulses on the CD-wire. Most significant byte is first data byte. |
0x26 | NOT SUPPORTED |
0x27 | NOT SUPPORTED |
0x28 | NOT SUPPORTED |
0x29 | NOT SUPPORTED |
0x2a | NOT SUPPORTED |
0x2e | NOT SUPPORTED |
0x2f | Stop activities in microcontroller to start watchdog reset. |
0x31 (modified) | Multiple display version of command 0x01. Display address is first byte after command. Supported addresses:
0x00 = main display, 0x01 = DAK display. |
0x32 (modified) | Multiple display version of command 0x02. Display address is first byte after command. Supported addresses: 0x00 = main display, 0x01 = DAK display. |
0x33 (modified) | Multiple display version of command 0x03. Display address is first byte after command. Supported addresses: 0x00 = main display, 0x01 = DAK display. For DAK display: Control code 0x13 is line number, not cursor position. Other control codes not supported. |
0x41 (modified) |
Set indicator status command; will set status on one indicator as off, on, slow blink or fast blink.
It will refer to KEY number (K), indicator number (I) and status selector with state (S). Many indicator can be set with one command: Example: 0x41+ KIS+KIS+....+KIS+ checksum (up to 9 KIS) Message ID: 0x41 : 1 byte Message size: 16 bits - Key number: 10 bits - Indicator number: 3 bits indicator 0 (binary 000): red LED indicator 1 (binary 001): NOT SUPPORTED indicator 2-7: for future use - Status selector (*): 2 bits status 0, binary 00, low priority: on status 1, binary 01, low priority: slow blink status 2, binary 10, low priority: fast blink status 3, binary 11, low priority: for future use - Status state: 1 bit state off, binary 0 off state on, binary 1 on (*): Status with higher the priority will override the lower. NOTE: Only keys # 0-99 are supported. |
0x42 | A station indicator reset command:
It will reset all the indicators on the station to state 0. Message ID: 0x42 The command has no parameters. |
0x43 | NOT SUPPORTED |
0x50 (new) | Display DAK page number. First data byte is the page to display, second byte is total number of DAK pages. |
0x51 (new) | Refresh DAK display. Lines that have not been updated since last refresh is deleted. |
DAK display texts
Located in file: <main.c>
DAK display text storage
Message command 0x33 is used to print text on the Direct Access Key display. But instead of printing the text directly, it is stored in the processor RAM (1) so that a change of DAK page later will not require all the text to be retransmitted. From the AlphaCom point of view, the DAK display texts are printed normally as for any display. During station start-up all texts are "printed" and the display is refreshed by command 0x51. At any time AlphaCom may change a DAK text, and it will replace the current text in RAM. The DAK display is automatically updated if any change was made on the currently displayed DAK page. (1): Actually, to reach the necessary amount of memory in the station, the EEPROM is used as "RAM" for DAK text on pages 4-9. For the user this should make no difference.
DAK display update
Message command 0x50 is used to select DAK page. Depending on the total amount of DAK pages compared to the DAK page number displayed, arrows up and/or down are displayed. Because the update is a quite heavy operation for the processor, it is separated into printing one line at a time each 10ms. An update will take a little more than 100ms total.
DAK key indicators
Inherited from CRM IV station, message command 0x41 is used to set DAK key indicators. This may be for example to highlight incoming or outgoing calls. Setting a key indicator will make the DAK text toggle (normal/inverted). If the key is not on the currently displayed DAK page, the corresponding arrow will blink instead.
LCD operations
Located in file: <lcd.c>
Hardware
Two LCDs of type POWERTIP PG12032 are connected to the processor. Each has two LCD drivers of type SED1520. The pins used on the processor are as follows:
PA0-PA7: Data bus PC7: A0 signal PC6: Read/Write signal PC5-PC4: Enable signals for LCD 0 (one signal for each driver) PC3-PC2: Enable signals for LCD 1 (one signal for each driver)
Printing to horizontal display
The main LCD (lower) in the station is mounted horizontally, and is used for normal ASCII text. The display itself is entirely graphical and does not contain any ASCII character set, so it has to be loaded in software.
For mechanical reasons, the LCD is mounted upside-down. The coordinates in the figure to the right correspond with the layout used in software; the lowlevel LCD values are actually opposite.
Each of the two LCD drivers controls half of the display, separated vertically. This means that when writing, the position must be checked to find out which of the drivers should be written to. The display size is 120*32 pixels, separated horizontally into 4 lines of 8 pixels height each. By writing data to the display, one column (8 pixels) is written at a time on the selected line. So with a 5*8 ASCII font, the display is written 6 times for each character, including one pixel-width space.
Printing to vertical display
The LCD for Direct Access Key texts (upper LCD) is mounted vertically, but the text should be oriented the same direction as for the main LCD. This means that the text must be tilted 90 degrees by software.
To orient the text in 90 degrees direction, an 8*8 bits buffer is used. Characters are put into this buffer one column at a time (see figure to the left), until the buffer is full. Then the whole buffer is printed, from top to bottom.
Because the space on the upper LCD is small, a separate ASCII character set is used on this display. These characters are from 2 to 5 pixels wide, but normal height (8 pixels).
Debug interface
Located in file: <debug.c>
To simplify software debugging several debug-specific functions have been made. All debug code is optionally included during compilation by selecting "#define" statements in the file <main.h>. All debug functions can be removed by deselecting "#define
DEBUG_ENABLED".
The different functions are listed below.
Output pin toggle
Controlled by: | #define DEBUG_TOGGLE_XXX (XXX = specified function to toggle on) |
Required code space: | Insignificant. |
The processor has one free pin, PB1. Toggling the pin at specific positions may be helpful for checking program execution timings on an oscilloscope.
UART1 communication
Controlled by: | #define DEBUG_UART1 |
Required code space: | Approx. 1500 bytes. |
The station hardware does not use the processor's UART1, pins PB2 (Rx) and PB3 (Tx). This is handy for debugging purposes, as data can easily be sent and received to a terminal or PC using standard RS-232 data format. Some additional hardware is required to give the correct signalling levels (that is, a self-powered RS-232 driver or optical transceiver).
The UART protocol is configured this way:
- 19200 baud
- 8 bits
- no parity
- 1 stop bit
When enabled, several data are continuously dumped to the UART. This includes:
- Startup message with software version, software build date and station boot-counter.
- Display text received from AlphaCom. Display messages are separated with a "|". DAK display messages are indicated by a "'".
- Notifications upon DAK display update start ("#") and end ("/#").
- Notifications upon DAK refresh start ("%") and end ("/%").
- Keys when pressed on the station.
All data sent is in ASCII text format.
UART1 console commands
Controlled by: | #define DEBUG_MESSAGES |
Required code space: | Approx. 500 bytes. |
Requires: | DEBUG_UART1 |
This function enables command messages to be received by UART1 Rx from terminal/PC. The messages are received as normal ASCII text, and are used to execute operations or dump status in the station.
List of UART1 debug command messages:
(Note: Some commands expect <enter> to be pressed after typing, others are executed on-the-fly when the command byte is received. All commands are case-sensitive.)
Command | Parameter | Description |
0 | Dial digit 0 | |
1 | Dial digit 1 | |
... | ... | |
9 | Dial digit 9 | |
d0 | Dial DAK page 0, digit 0 | |
d1 | Dial DAK page 0, digit 1 | |
... | ... | |
d9 | Dial DAK page 0, digit 9 | |
e0 | Dial DAK page 1, digit 0 (note: this is Left-arrow) | |
e1 | Dial DAK page 1, digit 1 (note: this is Up-arrow) | |
e2 | Dial DAK page 1, digit 2 (note: this is Down-arrow) | |
e3 | Dial DAK page 1, digit 3 (note: this is Right-arrow) | |
... | ... | |
e9 | Dial DAK page 1, digit 9 | |
M | Dial M-key | |
p | Toggle privacy status | |
<ESC> | Dial C-key and clear Debug command buffer | |
c[] <Enter> | Command list | Simulate AlphaCom command |
d <Enter> | Dump several RAM variables. | |
k[] <Enter> | 0 | Set all DAK key-indicators OFF |
1 | Set all DAK key-indicators ON | |
2 | Set all DAK key-indicators Blink slow | |
3 | Set all DAK key-indicators Blink fast | |
r <Enter> | Stop CPU and wait for watchdog reset | |
r[] <Enter> | (Any character) | Stop CPU with interrupts disabled and wait for watchdog reset |
s <Enter> | Report stack usage. |
Stack dump
Controlled by: | #define DEBUG_TEST_STACK |
Required code space: | Approx. 400 bytes. |
Requires: | DEBUG_UART1 |
This option is for dumping stack location and contents during startup. Studying the stack may be helpful when the program seems to crash for no reason. Normally this function is not needed. Dumping the stack contents will exceed the Tx1 buffer of 70 bytes and cause the processor to be occupied for some time.