Advertisement
laidlow

matrix.c

Aug 15th, 2013
552
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.01 KB | None | 0 0
  1. /*
  2. Copyright 2012 Jun Wako <[email protected]>
  3.  
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16. */
  17.  
  18. /*
  19.  * scan matrix
  20.  */
  21. #include <stdint.h>
  22. #include <stdbool.h>
  23. #include <avr/io.h>
  24. #include <util/delay.h>
  25. #include "print.h"
  26. #include "debug.h"
  27. #include "util.h"
  28. #include "matrix.h"
  29.  
  30.  
  31. #ifndef DEBOUNCE
  32. #   define DEBOUNCE 5
  33. #endif
  34. static uint8_t debouncing = DEBOUNCE;
  35.  
  36. /* matrix state(1:on, 0:off) */
  37. static matrix_row_t matrix[MATRIX_ROWS];
  38. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  39.  
  40. static matrix_row_t read_cols(void);
  41. static void init_cols(void);
  42. static void unselect_rows(void);
  43. static void select_row(uint8_t row);
  44.  
  45.  
  46. inline
  47. uint8_t matrix_rows(void)
  48. {
  49.     return MATRIX_ROWS;
  50. }
  51.  
  52. inline
  53. uint8_t matrix_cols(void)
  54. {
  55.     return MATRIX_COLS;
  56. }
  57.  
  58. void matrix_init(void)
  59. {
  60.     // initialize row and col
  61.     unselect_rows();
  62.     init_cols();
  63.  
  64.     // initialize matrix state: all keys off
  65.     for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  66.         matrix[i] = 0;
  67.         matrix_debouncing[i] = 0;
  68.     }
  69. }
  70.  
  71. uint8_t matrix_scan(void)
  72. {
  73.     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  74.         select_row(i);
  75.         _delay_us(30);  // without this wait read unstable value.
  76.         matrix_row_t cols = read_cols();
  77.         if (matrix_debouncing[i] != cols) {
  78.             matrix_debouncing[i] = cols;
  79.             if (debouncing) {
  80.                 debug("bounce!: "); debug_hex(debouncing); debug("\n");
  81.             }
  82.             debouncing = DEBOUNCE;
  83.         }
  84.         unselect_rows();
  85.     }
  86.  
  87.     if (debouncing) {
  88.         if (--debouncing) {
  89.             _delay_ms(1);
  90.         } else {
  91.             for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  92.                 matrix[i] = matrix_debouncing[i];
  93.             }
  94.         }
  95.     }
  96.  
  97.     return 1;
  98. }
  99.  
  100. bool matrix_is_modified(void)
  101. {
  102.     if (debouncing) return false;
  103.     return true;
  104. }
  105.  
  106. inline
  107. bool matrix_is_on(uint8_t row, uint8_t col)
  108. {
  109.     return (matrix[row] & ((matrix_row_t)1<<col));
  110. }
  111.  
  112. inline
  113. matrix_row_t matrix_get_row(uint8_t row)
  114. {
  115.     return matrix[row];
  116. }
  117.  
  118. void matrix_print(void)
  119. {
  120.     print("\nr/c 0123456789ABCDEF\n");
  121.     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  122.         phex(row); print(": ");
  123.         pbin_reverse16(matrix_get_row(row));
  124.         print("\n");
  125.     }
  126. }
  127.  
  128. uint8_t matrix_key_count(void)
  129. {
  130.     uint8_t count = 0;
  131.     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  132.         count += bitpop16(matrix[i]);
  133.     }
  134.     return count;
  135. }
  136.  
  137. /* Column pin configuration
  138.  * col: 0   1   2   3   4   5   6   7   8   9   10  11  12  13  14
  139.  * pin: F0  F1  F4  F5  F6  C7  C6  B6  B5  B4  B0  B1  B2  B3  B7
  140.  */
  141. static void  init_cols(void)
  142. {
  143.     // Input with pull-up(DDR:0, PORT:1)
  144.     DDRF  &= ~(1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0);
  145.     PORTF |=  (1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0);
  146.     DDRC  &= ~(1<<7 | 1<<6);
  147.     PORTC |=  (1<<7 | 1<<6);
  148.     DDRB  &= ~(1<<7 | 1<<6 | 1<< 5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
  149.     PORTB |=  (1<<7 | 1<<6 | 1<< 5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0);
  150. }
  151.  
  152. static matrix_row_t read_cols(void)
  153. {
  154.     return (PINF&(1<<0) ? 0 : (1<<0)) |
  155.            (PINF&(1<<1) ? 0 : (1<<1)) |
  156.            (PINF&(1<<4) ? 0 : (1<<2)) |
  157.            (PINF&(1<<5) ? 0 : (1<<3)) |
  158.            (PINF&(1<<6) ? 0 : (1<<4)) |
  159.            (PINC&(1<<7) ? 0 : (1<<5)) |
  160.            (PINC&(1<<6) ? 0 : (1<<6)) |
  161.            (PINB&(1<<6) ? 0 : (1<<7)) |
  162.            (PINB&(1<<5) ? 0 : (1<<8)) |
  163.            (PINB&(1<<4) ? 0 : (1<<9)) |
  164.            (PINB&(1<<0) ? 0 : (1<<10)) |
  165.            (PINB&(1<<1) ? 0 : (1<<11)) |
  166.            (PINB&(1<<2) ? 0 : (1<<12)) |
  167.            (PINB&(1<<3) ? 0 : (1<<13)) |
  168.            (PINB&(1<<7) ? 0 : (1<<14)) ;
  169. }
  170.  
  171. /* Row pin configuration
  172.  * row: 0   1   2   3   4
  173.  * pin: D0  D2  D3  D4  D5
  174.  */
  175. static void unselect_rows(void)
  176. {
  177.     // Hi-Z(DDR:0, PORT:0) to unselect
  178.     DDRD  &= ~0b00101111;
  179.     PORTD &= ~0b00101111;
  180. }
  181.  
  182. static void select_row(uint8_t row)
  183. {
  184.     // Output low(DDR:1, PORT:0) to select
  185.     switch (row) {
  186.         case 0:
  187.             DDRD  |= (1<<0);
  188.             PORTD &= ~(1<<0);
  189.             break;
  190.         case 1:
  191.             DDRD  |= (1<<2);
  192.             PORTD &= ~(1<<2);
  193.             break;
  194.         case 2:
  195.             DDRD  |= (1<<3);
  196.             PORTD &= ~(1<<3);
  197.             break;
  198.         case 3:
  199.             DDRD  |= (1<<4);
  200.             PORTD &= ~(1<<4);
  201.             break;
  202.         case 4:
  203.             DDRD  |= (1<<5);
  204.             PORTD &= ~(1<<5);
  205.             break;
  206.     }
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement