Actions

Difference between revisions of "Dual Display station - software description"

From Zenitel Wiki

(Key codes)
(Key codes)
Line 129: Line 129:
 
|COL5, ROW1 || KEY_DAK1 ||   || Key codes depend on which DAK page is currently displayed. (4)
 
|COL5, ROW1 || KEY_DAK1 ||   || Key codes depend on which DAK page is currently displayed. (4)
 
|-
 
|-
|COL5, ROW2 || KEY_DAK2 ||   || --"--
+
|COL5, ROW2 || KEY_DAK2 ||   || align=center | ---||---
 
|-
 
|-
 
|COL5, ROW3 || KEY_DAK3 ||   ||  
 
|COL5, ROW3 || KEY_DAK3 ||   ||  

Revision as of 08:44, 14 August 2007

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