diff --git a/right/src/buspal/microseconds/microseconds_pit.c b/right/src/buspal/microseconds/microseconds_pit.c index fe31636..3e9fecf 100644 --- a/right/src/buspal/microseconds/microseconds_pit.c +++ b/right/src/buspal/microseconds/microseconds_pit.c @@ -1,43 +1,15 @@ -/* - * @file microseconds.c - * @brief Microseconds timer driver source file - * - * Notes: The driver configure PIT as lifetime timer - */ #include "microseconds/microseconds.h" #include #include "bus_pal_hardware.h" -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -// Below MACROs are defined in order to keep this driver compabtile among all targets. -#if defined(PIT0) -#define PIT PIT0 -#endif -#if defined(SIM_SCGC6_PIT0_MASK) -#define SIM_SCGC6_PIT_MASK SIM_SCGC6_PIT0_MASK -#endif - -enum -{ +enum { kFrequency_1MHz = 1000000UL }; -//////////////////////////////////////////////////////////////////////////////// -// Variables -//////////////////////////////////////////////////////////////////////////////// -uint32_t s_tickPerMicrosecondMul8; //!< This value equal to 8 times ticks per microseconds +uint32_t s_tickPerMicrosecondMul8; // This value equals to 8 times ticks per microseconds -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Initialize timer facilities. -//! -//! It is initialize the timer to lifetime timer by chained channel 0 -//! and channel 1 together, and set b0th channels to maximum counting period +// Initialize the timer to lifetime timer by chained channel 0 and +// channel 1 together, and set both channels to maximum counting period. void microseconds_init(void) { uint32_t busClock; @@ -60,84 +32,65 @@ void microseconds_init(void) PIT->CHANNEL[0].TFLG = 1; // clear the timer 0 flag PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // start timer 0 - /* Calculate this value early - * The reason why use this solution is that lowest clock frequency supported by L0PB and L4KS - * is 0.25MHz, this solution will make sure ticks per microscond is greater than 0. - */ + // Calculate this value early + // The reason why use this solution is that lowest clock frequency supported by L0PB and L4KS + // is 0.25MHz, this solution will make sure ticks per microscond is greater than 0. busClock = get_bus_clock(); s_tickPerMicrosecondMul8 = (busClock * 8) / kFrequency_1MHz; // Make sure this value is greater than 0 - if (!s_tickPerMicrosecondMul8) - { + if (!s_tickPerMicrosecondMul8) { s_tickPerMicrosecondMul8 = 1; } } -//! @brief Shutdown the microsecond timer void microseconds_shutdown(void) { - // Turn off PIT: MDIS = 1, FRZ = 0 - PIT->MCR |= PIT_MCR_MDIS_MASK; + PIT->MCR |= PIT_MCR_MDIS_MASK; // Turn off PIT: MDIS = 1, FRZ = 0 } -//! @brief Read back running tick count uint64_t microseconds_get_ticks(void) { uint64_t valueH; uint32_t valueL; -#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && (FSL_FEATURE_PIT_HAS_LIFETIME_TIMER == 1) - valueH = PIT->LTMR64H; - valueL = PIT->LTMR64L; -#else // Make sure that there are no rollover of valueL. // Because the valueL always decreases, so, if the formal valueL is greater than // current value, that means the valueH is updated during read valueL. // In this case, we need to re-update valueH and valueL. - do - { + do { valueH = PIT->CHANNEL[1].CVAL; valueL = PIT->CHANNEL[0].CVAL; } while (valueL < PIT->CHANNEL[0].CVAL); -#endif // FSL_FEATURE_PIT_HAS_LIFETIME_TIMER // Invert to turn into an up counter return ~((valueH << 32) | valueL); } -//! @brief Returns the conversion of ticks to actual microseconds -//! This is used to seperate any calculations from getting a timer -// value for speed critical scenarios +// This is used to seperate any calculations from getting a timer +// value for speed critical scenarios uint32_t microseconds_convert_to_microseconds(uint32_t ticks) { // return the total ticks divided by the number of Mhz the system clock is at to give microseconds - return (8 * ticks / s_tickPerMicrosecondMul8); //!< Assumes system clock will never be < 0.125 Mhz + return (8 * ticks / s_tickPerMicrosecondMul8); // Assumes system clock will never be < 0.125 Mhz } -//! @brief Returns the conversion of microseconds to ticks uint64_t microseconds_convert_to_ticks(uint32_t microseconds) { return ((uint64_t)microseconds * s_tickPerMicrosecondMul8 / 8); } -//! @brief Delay specified time -//! -//! @param us Delay time in microseconds unit void microseconds_delay(uint32_t us) { uint64_t currentTicks = microseconds_get_ticks(); - - //! The clock value in Mhz = ticks/microsecond + // The clock value in Mhz = ticks/microsecond uint64_t ticksNeeded = ((uint64_t)us * s_tickPerMicrosecondMul8 / 8) + currentTicks; - while (microseconds_get_ticks() < ticksNeeded) - { - ; + while (microseconds_get_ticks() < ticksNeeded) { } } -//! @brief Gets the clock value used for microseconds driver +// Get the clock value used for microseconds driver uint32_t microseconds_get_clock(void) { return get_bus_clock(); diff --git a/right/src/buspal/microseconds/microseconds_sysclk.c b/right/src/buspal/microseconds/microseconds_sysclk.c deleted file mode 100644 index 387ce6b..0000000 --- a/right/src/buspal/microseconds/microseconds_sysclk.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * @file microseconds_sysclk.c - * @brief Microseconds sysclk timer driver source file - * - * Notes: The driver configure sysclk as lifetime timer - */ -#include "microseconds/microseconds.h" -#include "fsl_device_registers.h" -#include - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -enum -{ - kFrequency_1MHz = 1000000UL -}; - -//////////////////////////////////////////////////////////////////////////////// -// Variables -//////////////////////////////////////////////////////////////////////////////// -//! @brief Tracks number of timer rollovers for extended time keeping -//! with 32 bits here + the 24 bits of the counter for lower resolution -//! it will be years worth of time -volatile uint32_t s_highCounter; -uint32_t s_tickPerMicrosecondMul8; //!< This value equal to 8 times ticks per microseconds - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Initialize and start the timer facilities using the SysTick. -void microseconds_init(void) -{ - s_highCounter = 0; - SysTick->LOAD = SysTick_LOAD_RELOAD_Msk; // Set reload register to max value - SysTick->VAL = 0; // As per ARM reference initialization, set initial value to 0 - // interrupts are only triggered when going from 1 to 0 - - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | // Set timer to core clock frequency - SysTick_CTRL_TICKINT_Msk | // Enable interrupts on timeout - SysTick_CTRL_ENABLE_Msk; // Enable SysTick IRQ and SysTick Timer - - /* Calculate this value early - * The reason why use this solution is that lowest clock frequency supported by L0PB and L4KS - * is 0.25MHz, this solution will make sure ticks per microscond is greater than 0. - */ - s_tickPerMicrosecondMul8 = (SystemCoreClock * 8) / kFrequency_1MHz; - - // Make sure this value is greater than 0 - if (!s_tickPerMicrosecondMul8) - { - s_tickPerMicrosecondMul8 = 1; - } -} - -//! @brief Shutdown the microsecond timer -void microseconds_shutdown(void) -{ - // Disable the timer and interrupts from it - SysTick->CTRL = SysTick->CTRL & ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); - - // Clear the current value register - SysTick->VAL = 0; -} - -//! @brief Read back the running tick count -uint64_t microseconds_get_ticks(void) -{ - uint64_t retVal; - - //! The rollover counter keeps track of increments higher than the 24 bit SysTick counter - //! to combine them shift rollover up 24 bits and add the current ticks - uint32_t high; - uint32_t low; - - // Check for an overflow condition between the two reads above - do - { - high = s_highCounter; - low = ~SysTick->VAL & SysTick_LOAD_RELOAD_Msk; - } while (high != s_highCounter); - - retVal = ((uint64_t)high << 24) + low; - - return retVal; -} - -//! @brief Returns the conversion of ticks to actual microseconds -//! This is used to seperate any calculations from getting a timer -// value for timing sensitive scenarios -uint32_t microseconds_convert_to_microseconds(uint32_t ticks) -{ - // return the total ticks divided by the number of Mhz the system clock is at to give microseconds - return (8 * ticks / s_tickPerMicrosecondMul8); //!< Assumes system clock will never be < 0.125 Mhz -} - -//! @brief Returns the conversion of microseconds to ticks -uint64_t microseconds_convert_to_ticks(uint32_t microseconds) -{ - return ((uint64_t)microseconds * s_tickPerMicrosecondMul8 / 8); -} - -//! @brief Delay specified time -//! -//! @param us Delay time in microseconds unit -void microseconds_delay(uint32_t us) -{ - uint64_t currentTicks = microseconds_get_ticks(); - - //! The clock value in Mhz = ticks/microsecond - uint64_t ticksNeeded = ((uint64_t)us * s_tickPerMicrosecondMul8 / 8) + currentTicks; - while (microseconds_get_ticks() < ticksNeeded) - { - ; - } -} - -//! @brief Gets the clock value used for microseconds driver -uint32_t microseconds_get_clock(void) -{ - return SystemCoreClock; -} - -//! @brief Interrupt handler for the SysTick timer, this will just increment -// the rollover counter for extended time keeping -void SysTick_Handler(void) -{ - s_highCounter++; -} diff --git a/right/src/config_parser/parse_config.c b/right/src/config_parser/parse_config.c index a2b6304..c620258 100644 --- a/right/src/config_parser/parse_config.c +++ b/right/src/config_parser/parse_config.c @@ -48,7 +48,7 @@ parser_error_t ParseConfig(config_buffer_t *buffer) } } keymapCount = readCompactLength(buffer); - if (keymapCount > 255) { + if (keymapCount > MAX_KEYMAP_NUM) { return ParserError_InvalidKeymapCount; } for (uint8_t keymapIdx = 0; keymapIdx < keymapCount; keymapIdx++) { diff --git a/right/src/init_peripherals.c b/right/src/init_peripherals.c index 7767ce8..fc2cee7 100644 --- a/right/src/init_peripherals.c +++ b/right/src/init_peripherals.c @@ -12,6 +12,7 @@ #include "peripherals/adc.h" #include "init_peripherals.h" #include "eeprom.h" +#include "microseconds/microseconds_pit.c" void InitI2c() { port_pin_config_t pinConfig = { @@ -63,4 +64,5 @@ void InitPeripherals(void) InitI2cWatchdog(); #endif EEPROM_Init(); + microseconds_init(); } diff --git a/right/src/slave_drivers/is31fl3731_driver.c b/right/src/slave_drivers/is31fl3731_driver.c index 0ed41ad..f0995c6 100644 --- a/right/src/slave_drivers/is31fl3731_driver.c +++ b/right/src/slave_drivers/is31fl3731_driver.c @@ -64,7 +64,6 @@ void LedSlaveDriver_Init(uint8_t ledDriverId) { currentLedDriverState->phase = LedDriverPhase_SetFunctionFrame; currentLedDriverState->ledIndex = 0; LedDriverStates[LedDriverId_Left].setupLedControlRegistersCommand[7] |= 0b00000010; // Enable the LED of the ISO key. - memset(currentLedDriverState->targetLedValues, 0xff, LED_DRIVER_LED_COUNT); SetLeds(0xff); LedDisplay_SetText(3, "ABC"); } @@ -93,19 +92,23 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) { break; case LedDriverPhase_InitLedControlRegisters: I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH); - *ledDriverPhase = LedDriverPhase_Initialized; + *ledDriverPhase = LedDriverPhase_InitLedValues; break; - case LedDriverPhase_Initialized: - { -#ifdef LED_DRIVER_STRESS_TEST + case LedDriverPhase_InitLedValues: updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex; - memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); - I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, PWM_REGISTER_BUFFER_LENGTH); - *ledIndex += PMW_REGISTER_UPDATE_CHUNK_SIZE; + uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); + memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + *ledIndex, chunkSize); + I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, chunkSize + 1); + *ledIndex += chunkSize; if (*ledIndex >= LED_DRIVER_LED_COUNT) { *ledIndex = 0; + memcpy(currentLedDriverState->targetLedValues, currentLedDriverState->sourceLedValues, LED_DRIVER_LED_COUNT); +#ifndef LED_DRIVER_STRESS_TEST + *ledDriverPhase = LedDriverPhase_Initialized; +#endif } -#else + break; + case LedDriverPhase_Initialized: { uint8_t *sourceLedValues = currentLedDriverState->sourceLedValues; uint8_t *targetLedValues = currentLedDriverState->targetLedValues; @@ -147,7 +150,6 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) { if (*ledIndex >= LED_DRIVER_LED_COUNT) { *ledIndex = 0; } -#endif break; } } diff --git a/right/src/slave_drivers/is31fl3731_driver.h b/right/src/slave_drivers/is31fl3731_driver.h index f728b6c..293a112 100644 --- a/right/src/slave_drivers/is31fl3731_driver.h +++ b/right/src/slave_drivers/is31fl3731_driver.h @@ -26,6 +26,7 @@ LedDriverPhase_SetShutdownModeNormal, LedDriverPhase_SetFrame1, LedDriverPhase_InitLedControlRegisters, + LedDriverPhase_InitLedValues, LedDriverPhase_Initialized, } led_driver_phase_t; diff --git a/right/src/usb_protocol_handler.c b/right/src/usb_protocol_handler.c index 2d831f7..45d3a94 100644 --- a/right/src/usb_protocol_handler.c +++ b/right/src/usb_protocol_handler.c @@ -13,6 +13,7 @@ #include "peripherals/adc.h" #include "eeprom.h" #include "keymaps.h" +#include "microseconds/microseconds_pit.c" // Functions for setting error statuses @@ -200,10 +201,23 @@ void getKeyboardState(void) void getDebugInfo(void) { - GenericHidOutBuffer[1] = (I2C_Watchdog >> 0) & 0xff;; - GenericHidOutBuffer[2] = (I2C_Watchdog >> 8) & 0xff; - GenericHidOutBuffer[3] = (I2C_Watchdog >> 16) & 0xff; - GenericHidOutBuffer[4] = (I2C_Watchdog >> 24) & 0xff; + GenericHidOutBuffer[1] = I2C_Watchdog >> 0; + GenericHidOutBuffer[2] = I2C_Watchdog >> 8; + GenericHidOutBuffer[3] = I2C_Watchdog >> 16; + GenericHidOutBuffer[4] = I2C_Watchdog >> 24; + + uint64_t ticks = microseconds_get_ticks(); + uint32_t microseconds = microseconds_convert_to_microseconds(ticks); + uint32_t milliseconds = microseconds/1000; + + GenericHidOutBuffer[1] = (ticks >> 0) & 0xff;; + GenericHidOutBuffer[2] = (ticks >> 8) & 0xff; + GenericHidOutBuffer[3] = (ticks >> 16) & 0xff; + GenericHidOutBuffer[4] = (ticks >> 24) & 0xff; + GenericHidOutBuffer[5] = (ticks >> 32) & 0xff;; + GenericHidOutBuffer[6] = (ticks >> 40) & 0xff; + GenericHidOutBuffer[7] = (ticks >> 48) & 0xff; + GenericHidOutBuffer[8] = (ticks >> 56) & 0xff; } // The main protocol handler function