mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #429 from openmv/h7_cpufreq
Update CPU frequency scaling module.
This commit is contained in:
commit
0f1083d226
24
scripts/examples/02-Board-Control/cpufreq_scaling.py
Normal file
24
scripts/examples/02-Board-Control/cpufreq_scaling.py
Normal file
@ -0,0 +1,24 @@
|
||||
# CPU frequency scaling example.
|
||||
#
|
||||
# This example shows how to use the cpufreq module to change the CPU frequency on the fly.
|
||||
import sensor, image, time, cpufreq
|
||||
|
||||
sensor.reset() # Reset and initialize the sensor.
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
|
||||
sensor.set_framesize(sensor.QQVGA) # Set frame size to QVGA (320x240)
|
||||
sensor.skip_frames(time = 2000) # Wait for settings take effect.
|
||||
clock = time.clock() # Create a clock object to track the FPS.
|
||||
|
||||
def test_image_processing():
|
||||
for i in range(0, 50):
|
||||
clock.tick() # Update the FPS clock.
|
||||
img = sensor.snapshot() # Take a picture and return the image.
|
||||
img.find_edges(image.EDGE_CANNY, threshold=(50, 80))
|
||||
|
||||
print("\nFrequency Scaling Test...")
|
||||
for f in cpufreq.get_supported_frequencies():
|
||||
cpufreq.set_frequency(f)
|
||||
clock.reset()
|
||||
test_image_processing()
|
||||
freqs = cpufreq.get_current_frequencies()
|
||||
print("CPU Freq:%dMHz HCLK:%dMhz PCLK1:%dMhz PCLK2:%dMhz FPS:%.2f" %(freqs[0], freqs[1], freqs[2], freqs[3], clock.fps()))
|
||||
@ -1,18 +0,0 @@
|
||||
# Overclocking Example
|
||||
#
|
||||
# This example shows how to overclock your OMV2 cam to 216MHz. The camera will
|
||||
# stay overclocked until the next hard reset, if you need to keep this frequency
|
||||
# call the set_frequency function from your main script.
|
||||
#
|
||||
# WARNING: Overclocking to 216MHz should be safe, however Use at your own risk!
|
||||
|
||||
import cpufreq
|
||||
|
||||
# Print current CPU frequency
|
||||
print(cpufreq.get_frequency())
|
||||
|
||||
# Set frequency valid values are (120, 144, 168, 192, 216)
|
||||
cpufreq.set_frequency(cpufreq.CPUFREQ_216MHZ)
|
||||
|
||||
# Print current CPU frequency
|
||||
print(cpufreq.get_frequency())
|
||||
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* CPU frequency module.
|
||||
* CPU frequency scaling module.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -13,58 +13,138 @@
|
||||
#include <math.h>
|
||||
#include STM32_HAL_H
|
||||
#include "py_cpufreq.h"
|
||||
#include "py_helper.h"
|
||||
|
||||
enum cpufreq_freqs {
|
||||
CPUFREQ_120MHZ=0,
|
||||
CPUFREQ_144MHZ=1,
|
||||
CPUFREQ_168MHZ=2,
|
||||
CPUFREQ_192MHZ=3,
|
||||
CPUFREQ_216MHZ=4,
|
||||
CPUFREQ_MAX
|
||||
};
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
|
||||
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
#if defined(STM32H7)
|
||||
static const uint32_t cpufreq_freqs[] = {100, 200, 400};
|
||||
#elif defined(STM32F7)
|
||||
static const uint32_t cpufreq_pllq[] = {5, 6, 7, 8, 9};
|
||||
static const uint32_t cpufreq_freq[] = {120, 144, 168, 192, 216};
|
||||
static const uint32_t cpufreq_freqs[] = {120, 144, 168, 192, 216};
|
||||
static const uint32_t cpufreq_latency[] = { // Flash latency (see table 11)
|
||||
FLASH_LATENCY_3, FLASH_LATENCY_4, FLASH_LATENCY_5, FLASH_LATENCY_7, FLASH_LATENCY_7
|
||||
};
|
||||
#endif
|
||||
|
||||
void py_cpufreq_init0()
|
||||
uint32_t cpufreq_get_cpuclk()
|
||||
{
|
||||
uint32_t cpuclk = HAL_RCC_GetSysClockFreq();
|
||||
|
||||
#if defined(STM32H7)
|
||||
uint32_t flatency;
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
|
||||
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency);
|
||||
switch (RCC_ClkInitStruct.SYSCLKDivider) {
|
||||
case RCC_SYSCLK_DIV1:
|
||||
break;
|
||||
case RCC_SYSCLK_DIV2:
|
||||
cpuclk /= 2;
|
||||
break;
|
||||
case RCC_SYSCLK_DIV4:
|
||||
cpuclk /= 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return cpuclk;
|
||||
}
|
||||
|
||||
mp_obj_t py_cpufreq_get_frequency()
|
||||
mp_obj_t py_cpufreq_get_current_frequencies()
|
||||
{
|
||||
mp_obj_t tuple[4] = {
|
||||
mp_obj_new_int(HAL_RCC_GetSysClockFreq()),
|
||||
mp_obj_new_int(HAL_RCC_GetHCLKFreq()),
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK1Freq()),
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK2Freq()),
|
||||
mp_obj_new_int(cpufreq_get_cpuclk() / (1000000)),
|
||||
mp_obj_new_int(HAL_RCC_GetHCLKFreq() / (1000000)),
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK1Freq() / (1000000)),
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK2Freq() / (1000000)),
|
||||
};
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
}
|
||||
|
||||
mp_obj_t py_cpufreq_set_frequency(mp_obj_t cpufreq_idx_obj)
|
||||
mp_obj_t py_cpufreq_get_supported_frequencies()
|
||||
{
|
||||
mp_obj_t freq_list = mp_obj_new_list(0, NULL);
|
||||
for (int i=0; i<ARRAY_LENGTH(cpufreq_freqs); i++) {
|
||||
mp_obj_list_append(freq_list, mp_obj_new_int(cpufreq_freqs[i]));
|
||||
}
|
||||
return freq_list;
|
||||
}
|
||||
|
||||
mp_obj_t py_cpufreq_set_frequency(mp_obj_t cpufreq_obj)
|
||||
{
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
#if defined(STM32F7)
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||
#endif
|
||||
|
||||
// Check CPU frequency index range
|
||||
uint32_t cpufreq_idx = mp_obj_get_int(cpufreq_idx_obj);
|
||||
if (cpufreq_idx < 0 || cpufreq_idx >= CPUFREQ_MAX) {
|
||||
// Check if frequency is supported
|
||||
int cpufreq_idx = -1;
|
||||
uint32_t cpufreq = mp_obj_get_int(cpufreq_obj);
|
||||
for (int i=0; i<ARRAY_LENGTH(cpufreq_freqs); i++) {
|
||||
if (cpufreq == cpufreq_freqs[i]) {
|
||||
cpufreq_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Frequency is Not supported.
|
||||
if (cpufreq_idx == -1) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Unsupported frequency!"));
|
||||
}
|
||||
|
||||
// Return if frequency hasn't changed
|
||||
if (cpufreq_freq[cpufreq_idx] == (HAL_RCC_GetSysClockFreq()/1000000)) {
|
||||
// Return if frequency hasn't changed.
|
||||
if (cpufreq == (cpufreq_get_cpuclk()/(1000000))) {
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
#if defined(STM32H7)
|
||||
uint32_t flatency = FLASH_LATENCY_2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
|
||||
RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
|
||||
|
||||
switch (cpufreq) {
|
||||
case 100:
|
||||
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV4; // D1CPRE
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; // HPRE
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; // D2PPRE1
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; // D2PPRE2
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; // D1PPRE
|
||||
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; // D3PPRE
|
||||
break;
|
||||
|
||||
case 200:
|
||||
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV2; // D1CPRE
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; // HPRE
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; // D2PPRE1
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; // D2PPRE2
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; // D1PPRE
|
||||
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; // D3PPRE
|
||||
break;
|
||||
|
||||
case 400:
|
||||
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; // D1CPRE
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; // HPRE
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; // D2PPRE1
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; // D2PPRE2
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; // D1PPRE
|
||||
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; // D3PPRE
|
||||
break;
|
||||
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Unsupported frequency!"));
|
||||
break;
|
||||
}
|
||||
|
||||
#elif defined(STM32F7)
|
||||
// Select HSE as system clock source
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
|
||||
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK |
|
||||
RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
|
||||
// Configure the HCLK, PCLK1 and PCLK2 clocks dividers
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
|
||||
@ -80,7 +160,7 @@ mp_obj_t py_cpufreq_set_frequency(mp_obj_t cpufreq_idx_obj)
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLM = 12; // depends on HSE
|
||||
RCC_OscInitStruct.PLL.PLLN = cpufreq_freq[cpufreq_idx] * 2;
|
||||
RCC_OscInitStruct.PLL.PLLN = cpufreq_freqs[cpufreq_idx] * 2;
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = cpufreq_pllq[cpufreq_idx];
|
||||
|
||||
@ -90,30 +170,34 @@ mp_obj_t py_cpufreq_set_frequency(mp_obj_t cpufreq_idx_obj)
|
||||
}
|
||||
|
||||
// Select PLL as system clock source
|
||||
uint32_t flatency = cpufreq_latency[cpufreq_idx];
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, cpufreq_latency[cpufreq_idx]) != HAL_OK) {
|
||||
#endif
|
||||
|
||||
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, flatency) != HAL_OK) {
|
||||
// Initialization Error
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "RCC CLK Initialization Error!!"));
|
||||
}
|
||||
|
||||
// Do a soft-reset ?
|
||||
//nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Frequency is set!"));
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_cpufreq_get_frequency_obj, py_cpufreq_get_frequency);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_cpufreq_set_frequency_obj, py_cpufreq_set_frequency);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_cpufreq_get_current_frequencies_obj, py_cpufreq_get_current_frequencies);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_cpufreq_get_supported_frequencies_obj, py_cpufreq_get_supported_frequencies);
|
||||
#endif // defined(STM32F7) || defined(STM32H7)
|
||||
|
||||
static const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_cpufreq) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CPUFREQ_120MHZ), MP_OBJ_NEW_SMALL_INT(CPUFREQ_120MHZ) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CPUFREQ_144MHZ), MP_OBJ_NEW_SMALL_INT(CPUFREQ_144MHZ) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CPUFREQ_168MHZ), MP_OBJ_NEW_SMALL_INT(CPUFREQ_168MHZ) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CPUFREQ_192MHZ), MP_OBJ_NEW_SMALL_INT(CPUFREQ_192MHZ) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CPUFREQ_216MHZ), MP_OBJ_NEW_SMALL_INT(CPUFREQ_216MHZ) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_frequency), (mp_obj_t)&py_cpufreq_get_frequency_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_frequency), (mp_obj_t)&py_cpufreq_set_frequency_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_cpufreq) },
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_frequency), (mp_obj_t)&py_cpufreq_set_frequency_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_current_frequencies), (mp_obj_t)&py_cpufreq_get_current_frequencies_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_supported_frequencies), (mp_obj_t)&py_cpufreq_get_supported_frequencies_obj },
|
||||
#else
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_frequency), (mp_obj_t)&py_func_unavailable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_current_frequencies), (mp_obj_t)&py_func_unavailable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_supported_frequencies), (mp_obj_t)&py_func_unavailable_obj },
|
||||
#endif
|
||||
{ NULL, NULL },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
@ -337,13 +337,9 @@ Q(bssid)
|
||||
|
||||
// cpufreq Module
|
||||
Q(cpufreq)
|
||||
Q(CPUFREQ_120MHZ)
|
||||
Q(CPUFREQ_144MHZ)
|
||||
Q(CPUFREQ_168MHZ)
|
||||
Q(CPUFREQ_192MHZ)
|
||||
Q(CPUFREQ_216MHZ)
|
||||
Q(get_frequency)
|
||||
Q(set_frequency)
|
||||
Q(get_current_frequencies)
|
||||
Q(get_supported_frequencies)
|
||||
|
||||
// Get Pixel
|
||||
Q(get_pixel)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user