1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 /**
22 * \file
23 * \brief    Magnetic Stripe Reader driver
24 * \details  This driver can be used to configure and operate the Magnetic Stripe
25 *           Reader. It reads and decodes magnetic stripe data that is encoded
26 *           according to the ISO/IEC standard 7811.
27 * \details  This file defines the driver API including data types and function
28 *           prototypes.
29 */
30 
31 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_MSR_H_
32 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_MSR_H_
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /***** Definitions *****/
39 
40 /// Number of tracks on a card
41 #ifndef MSR_NUM_TRACKS
42 #define MSR_NUM_TRACKS 3
43 #endif
44 
45 #define MSR_MAX_SAMPLES 1536
46 
47 // Assuming nominal bit density of 210 bpi and 3.375 inch length
48 #define MSR_MAX_RAW_LEN_BITS (709)
49 #define MSR_MAX_RAW_LEN_BYTES ((MSR_MAX_RAW_LEN_BITS + 7) / 8)
50 #define MSR_MAX_RAW_LEN_HALFWORDS ((MSR_MAX_RAW_LEN_BITS + 15) / 16)
51 
52 /// Maximum size in bytes of decoded track characters (5-bit min to 8-bit max)
53 #define MSR_MAX_DEC_LEN (MSR_MAX_RAW_LEN_BITS / 5)
54 
55 /// Swipe direction: the card was swiped in the forward direction
56 #define MSR_FORWARD 0
57 /// Swipe direction: the card was swiped in the reverse direction
58 #define MSR_REVERSE 1
59 
60 /// Error codes
61 #define MSR_ERR_OK 0x00
62 #define MSR_ERR_BAD_LEN 0x01
63 #define MSR_ERR_START_SEN 0x02
64 #define MSR_ERR_END_SEN 0x04
65 #define MSR_ERR_OUTLIER 0x08
66 #define MSR_ERR_PARAM 0x10
67 #define MSR_ERR_LRC 0x40
68 #define MSR_ERR_PARITY 0x80
69 
70 /// Structure to contain result of a track decode
71 typedef struct {
72     uint8_t error_code; ///< Error code value
73     uint8_t parity_errs; ///< Number of characters with parity errors
74     uint8_t lrc; ///< LRC check value. A value of '0' indicates a
75         ///         successful LRC check. Any other value should be
76         ///         considered a failure.
77     uint8_t direction; ///< Swipe direction determined from decode
78     uint8_t len; ///< Number or decoded characters. This does not include
79         ///         the sentinels or the LRC.
80     uint16_t speed;
81     uint8_t data[MSR_MAX_DEC_LEN]; ///< The decoded data
82 } msr_decoded_track_t;
83 
84 /// MSR sample fields
85 typedef union {
86     struct {
87         uint16_t time : 9;
88         uint16_t amp : 7;
89     };
90     uint16_t value;
91 } msr_sample_t;
92 
93 /// Structure to contain raw MSR samples
94 typedef struct {
95     uint16_t len;
96     msr_sample_t data[MSR_MAX_SAMPLES];
97 } msr_samples_t;
98 
99 /***** Function Prototypes *****/
100 
101 /**
102 *   \brief    Initializes magnetic card reader hardware
103 *   \returns #E_NO_ERROR if everything is successful
104 */
105 int msr_init(void);
106 
107 /**
108 *   \brief    Initializes specified track
109 *   \param    track   track number (1 to 3)
110 */
111 void msr_init_track(unsigned int track);
112 
113 /**
114 *   \brief    Enables magnetic card reader
115 *   \pre      The reader should be initialized by calling msr_init() and then
116 *             waiting at least 100 us before calling this function.
117 */
118 void msr_enable(void);
119 
120 /**
121 *   \brief    Disables magnetic card reader
122 */
123 void msr_disable(void);
124 
125 /**
126 *   \brief    Task used to execute driver functionality.
127 *   \details  This function executes the internal driver functionality that
128 *             processes MSR events and reads stripe data. This function is used
129 *             when MSR interrupt servicing is disabled.
130 *   \returns  1 if all tracking reading is complete, 0 otherwise
131 */
132 int msr_task(void);
133 
134 /**
135 *   \brief    Decodes the specified track of data
136 *   \param    track           track number (1 to 3)
137 *   \param    decoded_track   track decode results
138 *   \returns  number of characters decoded
139 *   \note     This function has significant stack usage.
140 */
141 unsigned int msr_track_decode(unsigned int track, msr_decoded_track_t *decoded_track);
142 
143 /**
144 *   \brief    Registers an application callback function
145 *   \details  The callback function will be called after completion of the read
146 *             of all enabled card tracks
147 *   \details  Unregistering of the callback can be performed by calling this
148 *             function function with a NULL parameter.
149 *   \param    func  application callback function
150 */
151 void msr_set_complete_callback(void (*func)(void));
152 
153 /**
154 *   \brief    Retrieves the raw (undecoded) sample data for the specified track
155 *             of data
156 *   \param    track       track number (1 to 3)
157 *   \param    samples     pointer to where the sample data will be copied
158 *   \returns  number of samples retrieved
159 */
160 unsigned int mcr_get_track_samples(unsigned int track, msr_samples_t *samples);
161 
162 #ifdef __cplusplus
163 }
164 #endif
165 
166 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_MSR_H_
167