- Uses strobe setup from MatrixARM - New mapping for ADC sense - Initial ADC setup code (not optimized or configurable yet)capsense
@@ -64,10 +64,125 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { | |||
// ----- Functions ----- | |||
// TODO | |||
// - Support multiple ADCs | |||
// - Channel/Mux setup | |||
void ADC_setup( ADC adc ) | |||
{ | |||
// Enable ADC clock | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) | |||
SIM_SCGC6 |= SIM_SCGC6_ADC0; | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
SIM_SCGC6 |= SIM_SCGC6_ADC0; | |||
SIM_SCGC3 |= SIM_SCGC3_ADC1; | |||
#endif | |||
// Lookup base ADC register | |||
volatile unsigned int *ADC_SC1A = (unsigned int*)(&ADC_reg_offset_map[adc]); | |||
// Calculate Register offsets | |||
volatile unsigned int *ADC_CFG1 = (unsigned int*)(&ADC_SC1A) + 0x08; | |||
volatile unsigned int *ADC_CFG2 = (unsigned int*)(&ADC_SC1A) + 0x0C; | |||
volatile unsigned int *ADC_SC2 = (unsigned int*)(&ADC_SC1A) + 0x20; | |||
volatile unsigned int *ADC_SC3 = (unsigned int*)(&ADC_SC1A) + 0x24; | |||
volatile unsigned int *ADC_PG = (unsigned int*)(&ADC_SC1A) + 0x2C; | |||
volatile unsigned int *ADC_CLPS = (unsigned int*)(&ADC_SC1A) + 0x38; | |||
volatile unsigned int *ADC_CLP4 = (unsigned int*)(&ADC_SC1A) + 0x3C; | |||
volatile unsigned int *ADC_CLP3 = (unsigned int*)(&ADC_SC1A) + 0x40; | |||
volatile unsigned int *ADC_CLP2 = (unsigned int*)(&ADC_SC1A) + 0x44; | |||
volatile unsigned int *ADC_CLP1 = (unsigned int*)(&ADC_SC1A) + 0x48; | |||
volatile unsigned int *ADC_CLP0 = (unsigned int*)(&ADC_SC1A) + 0x4C; | |||
// Make sure calibration has stopped | |||
*ADC_SC3 = 0; | |||
// - CFG1 - | |||
// ADIV: (input)/2 divider | |||
// ADICLK: (bus)/2 divider | |||
// MODE: 16-bit | |||
// ADLSMP: Long sample | |||
//ADC_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(3) | ADC_CFG1_ADLSMP; | |||
// ADIV: (input)/8 divider | |||
*ADC_CFG1 = ADC_CFG1_ADIV(3) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(3) | ADC_CFG1_ADLSMP; | |||
// - CFG2 - | |||
// ADLSTS: 6 extra ADCK cycles; 10 ADCK cycles total sample time | |||
//ADC_CFG2 = ADC_CFG2_ADLSTS(2); | |||
// ADLSTS: 20 extra ADCK cycles; 24 ADCK cycles total sample time | |||
*ADC_CFG2 = ADC_CFG2_ADLSTS(0); | |||
// - SC2 - | |||
// REFSEL: Use default 3.3V reference | |||
*ADC_SC2 = ADC_SC2_REFSEL(0); | |||
/* | |||
// Setup VREF to 1.2 V | |||
VREF_TRM = 0x60; | |||
VREF_SC = 0xE1; // Enable 1.2 volt ref | |||
// REFSEL: Use 1.2V reference VREF | |||
*ADC_SC2 = ADC_SC2_REFSEL(1); | |||
*/ | |||
// - SC3 - | |||
// CAL: Start calibration | |||
// AVGE: Enable hardware averaging | |||
// AVGS: 32 samples averaged | |||
// 32 sample averaging | |||
*ADC_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | ADC_SC3_AVGS(3); | |||
// Wait for calibration | |||
while ( *ADC_SC3 & ADC_SC3_CAL ); | |||
// Apply computed calibration offset | |||
// XXX Note, for single-ended, only the plus side offsets have to be applied | |||
// For differential the minus side also has to be set as well | |||
__disable_irq(); // Disable interrupts while reading/setting offsets | |||
// Set calibration | |||
// ADC Plus-Side Gain Register | |||
// See Section 31.4.7 in the datasheet (mk20dx256vlh7) for details | |||
uint16_t sum = *ADC_CLPS + *ADC_CLP4 + *ADC_CLP3 + *ADC_CLP2 + *ADC_CLP1 + *ADC_CLP0; | |||
sum = (sum / 2) | 0x8000; | |||
*ADC_PG = sum; | |||
__enable_irq(); // Re-enable interrupts | |||
// Start ADC reading loop | |||
// - SC1A - | |||
// ADCH: Channel DAD0 (A10) | |||
// AIEN: Enable interrupt | |||
//*ADC_SC1A = ADC_SC1_AIEN | ADC_SC1_ADCH(0); | |||
// Enable ADC0 IRQ Vector | |||
//NVIC_ENABLE_IRQ( IRQ_ADC0 ); | |||
} | |||
// TODO | |||
// - Enable/Disable strobe detection (IBM) | |||
// - Setup strobe matrix | |||
void Strobe_setup() | |||
{ | |||
} | |||
// TODO | |||
// - Setup ADCs | |||
// - Setup ADC muxes | |||
// - Setup voltage stab | |||
void Sense_setup() | |||
{ | |||
} | |||
void Matrix_setup() | |||
{ | |||
// Register Matrix CLI dictionary | |||
CLI_registerDictionary( matrixCLIDict, matrixCLIDictName ); | |||
// Setup sense | |||
Sense_setup(); | |||
// Setup strobes | |||
Strobe_setup(); | |||
} | |||
// Scan the matrix for keypresses |
@@ -27,8 +27,145 @@ | |||
// ----- Enums ----- | |||
// Freescale MK20s have GPIO ports A...E | |||
typedef enum Port { | |||
Port_A = 0, | |||
Port_B = 1, | |||
Port_C = 2, | |||
Port_D = 3, | |||
Port_E = 4, | |||
} Port; | |||
// Each port has a possible 32 pins | |||
typedef enum Pin { | |||
Pin_0 = 0, | |||
Pin_1 = 1, | |||
Pin_2 = 2, | |||
Pin_3 = 3, | |||
Pin_4 = 4, | |||
Pin_5 = 5, | |||
Pin_6 = 6, | |||
Pin_7 = 7, | |||
Pin_8 = 8, | |||
Pin_9 = 9, | |||
Pin_10 = 10, | |||
Pin_11 = 11, | |||
Pin_12 = 12, | |||
Pin_13 = 13, | |||
Pin_14 = 14, | |||
Pin_15 = 15, | |||
Pin_16 = 16, | |||
Pin_17 = 17, | |||
Pin_18 = 18, | |||
Pin_19 = 19, | |||
Pin_20 = 20, | |||
Pin_21 = 21, | |||
Pin_22 = 22, | |||
Pin_23 = 23, | |||
Pin_24 = 24, | |||
Pin_25 = 25, | |||
Pin_26 = 26, | |||
Pin_27 = 27, | |||
Pin_28 = 28, | |||
Pin_29 = 29, | |||
Pin_30 = 30, | |||
Pin_31 = 31, | |||
} Pin; | |||
// Depending on the microcontroller, it can have 1 or more ADCs | |||
typedef enum ADC { | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) | |||
ADC_0 = 0, | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC_0 = 0, | |||
ADC_1 = 1, | |||
#endif | |||
} ADC; | |||
// ADC Register offset map | |||
unsigned int *ADC_reg_offset_map[] = { | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) | |||
(unsigned int*)(&ADC0_SC1A), | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
(unsigned int*)(&ADC0_SC1A), | |||
(unsigned int*)(&ADC1_SC1A), | |||
#endif | |||
}; | |||
// Each ADC has a possible 32 channels | |||
typedef enum Channel { | |||
Channel_0 = 0, | |||
Channel_1 = 1, | |||
Channel_2 = 2, | |||
Channel_3 = 3, | |||
Channel_4 = 4, | |||
Channel_5 = 5, | |||
Channel_6 = 6, | |||
Channel_7 = 7, | |||
Channel_8 = 8, | |||
Channel_9 = 9, | |||
Channel_10 = 10, | |||
Channel_11 = 11, | |||
Channel_12 = 12, | |||
Channel_13 = 13, | |||
Channel_14 = 14, | |||
Channel_15 = 15, | |||
Channel_16 = 16, | |||
Channel_17 = 17, | |||
Channel_18 = 18, | |||
Channel_19 = 19, | |||
Channel_20 = 20, | |||
Channel_21 = 21, | |||
Channel_22 = 22, | |||
Channel_23 = 23, | |||
Channel_24 = 24, | |||
Channel_25 = 25, | |||
Channel_26 = 26, | |||
Channel_27 = 27, | |||
Channel_28 = 28, | |||
Channel_29 = 29, | |||
Channel_30 = 30, | |||
Channel_31 = 31, | |||
} Channel; | |||
// Type of pin | |||
typedef enum Type { | |||
Type_StrobeOn, | |||
Type_StrobeOff, | |||
Type_StrobeSetup, | |||
Type_Sense, | |||
Type_SenseSetup, | |||
} Type; | |||
// Keypress States | |||
typedef enum KeyPosition { | |||
KeyState_Off = 0, | |||
KeyState_Press = 1, | |||
KeyState_Hold = 2, | |||
KeyState_Release = 3, | |||
KeyState_Invalid, | |||
} KeyPosition; | |||
// ----- Structs ----- | |||
// Struct container for defining Strobe pins | |||
typedef struct GPIO_Pin { | |||
Port port; | |||
Pin pin; | |||
} GPIO_Pin; | |||
// Struct container for defining Sense pins | |||
typedef struct ADC_Pin { | |||
Port port; | |||
Pin pin; | |||
ADC adc; | |||
Channel ch; | |||
} ADC_Pin; | |||
// ----- Functions ----- | |||
void Matrix_setup(); |
@@ -16,5 +16,12 @@ | |||
#pragma once | |||
// TODO | |||
// ----- Macros ----- | |||
// Convenience Macros | |||
#define gpio( port, pin ) { Port_##port, Pin_##pin } | |||
#define sense( port, pin, adc, ch ) { Port_##port, Pin_##pin, ADC_##adc, Channel_##ch } | |||
#define Matrix_colsNum sizeof( Matrix_cols ) / sizeof( GPIO_Pin ) | |||
#define Matrix_rowsNum sizeof( Matrix_rows ) / sizeof( GPIO_Pin ) | |||
#define Matrix_maxKeys sizeof( Matrix_scanArray ) / sizeof( KeyState ) | |||
@@ -25,8 +25,39 @@ | |||
// ----- Matrix Definition ----- | |||
// CapTest | |||
// (TODO) | |||
// | |||
// Strobe | |||
// PTB0..3,16,17 | |||
// PTC4,5 | |||
// PTD0 | |||
// | |||
// Sense | |||
// PTD1..7 | |||
// -- Strobes -- | |||
// Format | |||
// gpio( <port letter>, <port #> ) | |||
// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 | |||
// Not all chips have access to all of these pins (most don't have 160 pins :P) | |||
// | |||
GPIO_Pin Matrix_strobe[] = { gpio(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,5), gpio(D,0) }; | |||
// -- Sense -- | |||
// Format | |||
// sense( <port letter>, <port #>, <adc #>, <adc channel #> ) | |||
// Freescale ARM MK20's support 32 ADC channels | |||
// However, not every channel is useful for reading from an input pin. | |||
// | |||
// NOTE: Be careful that you are not using a strobe and a sense at the same time! | |||
// | |||
ADC_Pin Matrix_sense[] = { sense(B,4,0,5) }; | |||
// TODO | |||
// Define possible strobes | |||
// Define possible senses | |||
// Misc pins required for control | |||