diff --git a/98-kiibohd.rules b/98-kiibohd.rules index 5e28301..d00a8b2 100644 --- a/98-kiibohd.rules +++ b/98-kiibohd.rules @@ -5,6 +5,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:= # Kiibohd Serial Interface KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" # Kiibohd Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" # DFU Bootloader (MCHCK) diff --git a/Lib/CMake/arm.cmake b/Lib/CMake/arm.cmake index be04de2..f6e975f 100644 --- a/Lib/CMake/arm.cmake +++ b/Lib/CMake/arm.cmake @@ -119,7 +119,7 @@ message( "${COMPILER_SRCS}" ) message( STATUS "Bootloader Type:" ) if ( "${CHIP}" MATCHES "mk20dx128vlf5" OR "${CHIP}" MATCHES "mk20dx256vlh7" ) set( VENDOR_ID "0x1C11" ) - set( PRODUCT_ID "0xB04D" ) + set( PRODUCT_ID "0xF05C" ) set( BOOT_VENDOR_ID "0x1C11" ) set( BOOT_PRODUCT_ID "0xB007" ) set( BOOT_DFU_ALTNAME "Kiibohd DFU" ) @@ -127,7 +127,7 @@ if ( "${CHIP}" MATCHES "mk20dx128vlf5" OR "${CHIP}" MATCHES "mk20dx256vlh7" ) message( "dfu" ) elseif ( "${CHIP}" MATCHES "mk20dx128" OR "${CHIP}" MATCHES "mk20dx256" ) set( VENDOR_ID "0x1C11" ) - set( PRODUCT_ID "0xB04D" ) + set( PRODUCT_ID "0xF05C" ) set( BOOT_VENDOR_ID "0x16c0" ) # TODO Double check, this is likely incorrect set( BOOT_PRODUCT_ID "0x0487" ) set( TEENSY 1 ) diff --git a/Lib/mk20dx.h b/Lib/mk20dx.h index 277cfed..34004bf 100644 --- a/Lib/mk20dx.h +++ b/Lib/mk20dx.h @@ -1103,6 +1103,8 @@ // Chapter 36: Periodic Interrupt Timer (PIT) #define PIT_MCR *(volatile uint32_t *)0x40037000 // PIT Module Control Register +#define PIT_MCR_MDIS 0x02 // PIT Module disable +#define PIT_MCR_FRZ 0x01 // PIT Module debug mode freeze #define PIT_LDVAL0 *(volatile uint32_t *)0x40037100 // Timer Load Value Register #define PIT_CVAL0 *(volatile uint32_t *)0x40037104 // Current Timer Value Register #define PIT_TCTRL0 *(volatile uint32_t *)0x40037108 // Timer Control Register @@ -1119,6 +1121,10 @@ #define PIT_CVAL3 *(volatile uint32_t *)0x40037134 // Current Timer Value Register #define PIT_TCTRL3 *(volatile uint32_t *)0x40037138 // Timer Control Register #define PIT_TFLG3 *(volatile uint32_t *)0x4003713C // Timer Flag Register +#define PIT_TCTRL_CHN 0x04 // Chain mode, n-1 PIT Channel needs to expire before incrementing +#define PIT_TCTRL_TIE 0x02 // Timer interrupt enable +#define PIT_TCTRL_TEN 0x01 // Timer enable +#define PIT_TFLG_TIF 0x01 // Clears interrupt // Chapter 37: Low-Power Timer (LPTMR) #define LPTMR0_CSR *(volatile uint32_t *)0x40040000 // Low Power Timer Control Status Register diff --git a/Lib/pin_map.teensy3 b/Lib/pin_map.teensy3 index a0b77c9..3ae9ff4 100644 --- a/Lib/pin_map.teensy3 +++ b/Lib/pin_map.teensy3 @@ -1,7 +1,7 @@ // Pin Name Function Hardware // ---------------------------------- -// 0 PTB16 RX0 -// 1 PTB17 TX0 +// 0 PTB16 RX0 SOUT1 +// 1 PTB17 TX0 SIN1 // 2 PTD0 PCS0 // 3 PTA12 FTM1_CH0 PWM (CAN TX - Teensy 3.1) I2S_TXD0 // 4 PTA13 FTM1_CH1 PWM (CAN RX - Teensy 3.1) I2S_TX_FS @@ -26,12 +26,12 @@ // 23 PTC2 FTM0_CH1 PWM PCS2 I2S_TX_FS // 24 PTA5 (FTM0_CH2) I2S_TX_BCLK // 25 PTB19 (PWM - Teensy 3.1) I2S_TX_FS -// 26 PTE1 RX1 SCL1 +// 26 PTE1 RX1 SCL1 SOUT1 SIN1 // 27 PTC9 I2S_RX_BCLK // 28 PTC8 I2S_MCLK // 29 PTC10 (SCL1 - Teensy 3.1) I2S_RX_FS // 30 PTC11 (SDA1 - Teensy 3.1) I2S_RXD1 -// 31 PTE0 TX1 SDA1 +// 31 PTE0 TX1 SDA1 PCS1-1 // 32 PTB18 (PWM - Teensy 3.1) I2S_TX_BCLK // 33 PTA4 (FTM0_CH1) // 34 analog only diff --git a/Output/pjrcUSB/arm/usb_desc.h b/Output/pjrcUSB/arm/usb_desc.h index f0b6447..f5f1096 100644 --- a/Output/pjrcUSB/arm/usb_desc.h +++ b/Output/pjrcUSB/arm/usb_desc.h @@ -61,9 +61,9 @@ #define CDC_IAD_DESCRIPTOR 1 #define CDC_STATUS_INTERFACE 0 #define CDC_DATA_INTERFACE 1 // Serial -#define CDC_ACM_ENDPOINT 0 -#define CDC_RX_ENDPOINT 1 -#define CDC_TX_ENDPOINT 2 +#define CDC_ACM_ENDPOINT 1 +#define CDC_RX_ENDPOINT 2 +#define CDC_TX_ENDPOINT 3 #define CDC_ACM_SIZE 16 #define CDC_RX_SIZE 64 #define CDC_TX_SIZE 64 diff --git a/main.c b/main.c index c2c0b87..407718f 100644 --- a/main.c +++ b/main.c @@ -44,6 +44,10 @@ // ----- Function Declarations ----- +void cliFunc_down ( char* args ); +void cliFunc_stop ( char* args ); +void cliFunc_up ( char* args ); + void cliFunc_contRead ( char* args ); void cliFunc_distRead ( char* args ); void cliFunc_free ( char* args ); @@ -66,6 +70,19 @@ void continuityTest(); // ----- Variables ----- +// Force Gauge command dictionary +CLIDict_Entry( up, "Enable motor up signal" ); +CLIDict_Entry( down, "Enable motor down signal" ); +CLIDict_Entry( stop, "Stop motor movement" ); + +CLIDict_Def( forceGaugeCLIDict, "Force Curve Gauge Commands" ) = { + CLIDict_Item( down ), + CLIDict_Item( stop ), + CLIDict_Item( up ), + { 0, 0, 0 } // Null entry for dictionary end +}; + + #if 0 // Force Gauge command dictionary char* forceGaugeCLIDictName = "Force Curve Gauge Commands"; @@ -224,10 +241,216 @@ inline void forceSetup() } #endif +// ------ Distance Measurement ------ + +// PWM Input Interrupt +volatile uint8_t distance_pulses_on = 0; +void pit0_isr() +{ + //dbug_print("YUSH"); + // If pulses are on, turn off + if ( distance_pulses_on ) + { + // Disable FTM PWM + FTM0_C7SC = 0x00; + } + // Otherwise turn them on + else + { + // Set FTM to PWM output - Edge Aligned, High-true pulses + FTM0_C7SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 01 + } + + distance_pulses_on = !distance_pulses_on; + + // Clear the interrupt + PIT_TFLG0 = PIT_TFLG_TIF; +} + +inline void distance_setup() +{ + // Setup distance read parameters for iGaging Distance Scale + // freq = 9kHz + // duty_cycle = 20% + // high_delay = (1/freq) * (duty_cycle/100) + // low_delay = (1/freq) * ((100-duty_cycle)/100) + + // Setup PWM source + SIM_SCGC6 |= SIM_SCGC6_FTM0; + + // Disable write protect and allow access to all the registers + FTM0_CNT = 0; // Reset counter + + // Set FTM to PWM output - Edge Aligned, High-true pulses + FTM0_C7SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 01 + + // System clock, /w prescalar setting of 0 + FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); + + // PWM Period + // 48 MHz / 9 kHz = 5333.333 or 0x14d5 + FTM0_MOD = 0x14d5; + + // Clock source for iGaging calipers + FTM0_C7V = 0x042A; // 0x14d5 * 0.20 = 1066.6 or 0x42A + PORTD_PCR7 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4) | PORT_PCR_PE; + + // Indicate that pulses have been enabled + distance_pulses_on = 1; + + + // Setup PIT (Programmable Interrupt Timer) + SIM_SCGC6 |= SIM_SCGC6_PIT;; + PIT_MCR = 0x00; // Enable module, do not freeze timers in debug mode + + // Timer Count-down value + // (48 MHz / 9 KHz) * 21 cycles = 112 000 ticks (0x1B580) + PIT_LDVAL0 = 0x1B580; + //PIT_LDVAL0 = 0x2DC6C00; // Once per second + + // Enable Timer, Enable interrupt + PIT_TCTRL0 = PIT_TCTRL_TIE | PIT_TCTRL_TEN; + + // Enable PIT Ch0 interrupt + NVIC_ENABLE_IRQ( IRQ_PIT_CH0 ); +} + + + +// ------ Motor Control ----- + +void motor_stop() +{ + // Pull high to stop motors + GPIOC_PSOR |= (1 << 8); + GPIOC_PSOR |= (1 << 9); +} + +void motor_up_start() +{ + // First disable motor + motor_stop(); + + // Then check if limit switch is enabled + if ( !( GPIOC_PDIR & (1 << 10) ) ) + { + erro_print("Upper limit switch triggered."); + return; + } + + GPIOC_PCOR |= (1 << 8); +} + +void motor_down_start() +{ + // First disable motor + motor_stop(); + + // Then check if limit switch is enabled + if ( !( GPIOE_PDIR & (1 << 0) ) ) + { + erro_print("Lower limit switch triggered."); + return; + } + + GPIOC_PCOR |= (1 << 9); +} + +void portc_isr() +{ + // Check each of the interrupts and clear them + if ( PORTC_PCR10 & PORT_PCR_ISF ) + { + motor_stop(); + warn_print("Upper Limit Switch!"); + PORTC_PCR10 |= PORT_PCR_ISF; + } +} + +void porte_isr() +{ + // Check each of the interrupts and clear them + if ( PORTE_PCR0 & PORT_PCR_ISF ) + { + motor_stop(); + warn_print("Lower Limit Switch!"); + PORTE_PCR0 |= PORT_PCR_ISF; + } +} + +// Limit switch interrupt setup +// Should be the highest level interrupt (to avoid having the test stand destroy itself) +inline void limit_switch_setup() +{ + // TODO Decide on which pins to use + // Currently PTC10 and PTE0 + + // Enable GPIO, Interrupt on falling edge, Passive input filter, Pullups + PORTC_PCR10 = PORT_PCR_MUX(1) | PORT_PCR_IRQC(10) | PORT_PCR_PFE | PORT_PCR_PE | PORT_PCR_PS; + PORTE_PCR0 = PORT_PCR_MUX(1) | PORT_PCR_IRQC(10) | PORT_PCR_PFE | PORT_PCR_PE | PORT_PCR_PS; + + // Set GPIO as input + GPIOC_PDIR |= (1 << 10); + GPIOE_PDIR |= (1 << 0); + + // Enable IRQ + NVIC_ENABLE_IRQ( IRQ_PORTC ); + NVIC_ENABLE_IRQ( IRQ_PORTE ); + + // Set IRQ has highest priority + NVIC_SET_PRIORITY( IRQ_PORTC, 0 ); + NVIC_SET_PRIORITY( IRQ_PORTE, 0 ); +} + +inline void motor_control_setup() +{ + // TODO Decide on which pins to use + // Currently PTC8 and PTC9 + + // Stop motor + motor_stop(); + + // Set GPIO as output pins + GPIOC_PDDR |= (1 << 8); + GPIOC_PDDR |= (1 << 9); + + // Enable GPIO, slow slew rate, high drive strength + PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + PORTC_PCR9 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); +} + + + + + // Main execution function int main() { + // Enable CLI + CLI_init(); + + // Register Force Gauge CLI dictionary + CLI_registerDictionary( forceGaugeCLIDict, forceGaugeCLIDictName ); + + // Setup - TODO + distance_setup(); + limit_switch_setup(); + motor_control_setup(); + + // Setup Modules + Output_setup(); + + // Main Detection Loop + while ( 1 ) + { + // Process CLI + CLI_process(); + + // TODO + } + + #if 0 // Setup force gauge forceSetup(); @@ -487,15 +710,30 @@ void cliFunc_distRead( char* args ) delay( 50 ); } } +#endif +void cliFunc_up( char* args ) +{ + motor_up_start(); +} + +void cliFunc_down( char* args ) +{ + motor_down_start(); +} + +void cliFunc_stop( char* args ) +{ + motor_stop(); +} void cliFunc_free( char* args ) { // Set the forceDistanceRead to 1, which will read until start has passed twice - forceDistanceRead = 1; + //forceDistanceRead = 1; } - +#if 0 void imadaVerboseRead( char* cmd ) { // Write command to data register