Adding initial matrix configuration structure
- Uses strobe setup from MatrixARM - New mapping for ADC sense - Initial ADC setup code (not optimized or configurable yet)
This commit is contained in:
parent
39dbb85c1a
commit
271b0af9b9
@ -64,10 +64,125 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = {
|
|||||||
|
|
||||||
// ----- Functions -----
|
// ----- 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()
|
void Matrix_setup()
|
||||||
{
|
{
|
||||||
// Register Matrix CLI dictionary
|
// Register Matrix CLI dictionary
|
||||||
CLI_registerDictionary( matrixCLIDict, matrixCLIDictName );
|
CLI_registerDictionary( matrixCLIDict, matrixCLIDictName );
|
||||||
|
|
||||||
|
// Setup sense
|
||||||
|
Sense_setup();
|
||||||
|
|
||||||
|
// Setup strobes
|
||||||
|
Strobe_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the matrix for keypresses
|
// Scan the matrix for keypresses
|
||||||
|
@ -27,8 +27,145 @@
|
|||||||
|
|
||||||
// ----- Enums -----
|
// ----- 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 -----
|
// ----- 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 -----
|
// ----- Functions -----
|
||||||
|
|
||||||
void Matrix_setup();
|
void Matrix_setup();
|
||||||
|
@ -16,5 +16,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#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 -----
|
// ----- 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
|
// TODO
|
||||||
// Define possible strobes
|
|
||||||
// Define possible senses
|
|
||||||
// Misc pins required for control
|
// Misc pins required for control
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user