Skip to content

Commit fe8ee2a

Browse files
committed
Implement sample code init function for noneos-sdk and FreeRTOS
1 parent 8a26a8e commit fe8ee2a

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

platform.py

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,283 @@ def configure_debug_session(self, debug_config):
240240
debug_config.server["arguments"].extend(
241241
["-c", "adapter speed %s" % debug_config.speed]
242242
)
243+
244+
def get_noneos_header_for_mcu(self, mcu):
245+
header = None
246+
if mcu.startswith("ch32v00") or mcu.startswith("ch32m0"):
247+
if mcu.startswith("ch32v003"):
248+
header = "ch32v00x.h"
249+
else:
250+
header = "ch32v00X.h"
251+
elif mcu.startswith("ch32v10"):
252+
header = "ch32v10x.h"
253+
elif mcu.startswith("ch32v20"):
254+
header = "ch32v20x.h"
255+
elif mcu.startswith("ch32v30"):
256+
header = "ch32v30x.h"
257+
elif mcu.startswith("ch32l0"):
258+
header = "ch32l103.h"
259+
elif mcu.startswith("ch32x0"):
260+
header = "ch32x305.h"
261+
elif mcu.startswith("ch641"):
262+
header = "ch641.h"
263+
elif mcu.startswith("ch643"):
264+
header = "ch643.h"
265+
elif mcu.startswith("ch5"):
266+
header = mcu[0:len("ch5x")].upper() + "x_common.h"
267+
return header
268+
269+
def generate_sample_code(self, config, environment):
270+
frameworks = config.get(f"env:{environment}", "framework", None)
271+
if frameworks is None or len(frameworks) != 1 or (len(frameworks) == 1 and frameworks[0] == "arduino"):
272+
raise NotImplementedError()
273+
# we've made sure this is a single framework project.
274+
framework = frameworks[0]
275+
main_content = ""
276+
is_cpp_project = False
277+
board = config.get("env:%s" % environment, "board")
278+
board_config = self.board_config(board)
279+
mcu = str(board_config.get("build.mcu", "")).lower()
280+
additional_files: list[tuple[str, str]] = []
281+
# commonly needed
282+
is_l10x = mcu.startswith("ch32l1")
283+
is_v00Xx = mcu.startswith("ch32m0") or (mcu.startswith("ch32v00") and not mcu.startswith("ch32v003"))
284+
is_ch6x = mcu.startswith("ch6")
285+
is_ch5x = mcu.startswith("ch5")
286+
if framework == "noneos-sdk":
287+
gpio_port = "GPIOC" if not is_ch6x else "GPIOA"
288+
gpio_pin = "GPIO_Pin_1" if not is_ch6x else "GPIO_Pin_0"
289+
gpio_clock_enable = ""
290+
if is_l10x or is_v00Xx:
291+
gpio_clock_enable = "RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOC, ENABLE)"
292+
elif is_ch6x:
293+
gpio_clock_enable = "RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)"
294+
else:
295+
gpio_clock_enable = "RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE)"
296+
hdr = self.get_noneos_header_for_mcu(mcu)
297+
if hdr is None:
298+
raise NotImplementedError(
299+
"Cannot determine NoneOS SDK header for the selected board"
300+
)
301+
if not is_ch5x:
302+
main_content = """
303+
#include <%s>
304+
#include <debug.h>
305+
306+
#define BLINKY_GPIO_PORT %s
307+
#define BLINKY_GPIO_PIN %s
308+
#define BLINKY_CLOCK_ENABLE %s
309+
310+
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
311+
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
312+
313+
int main(void) {
314+
SystemCoreClockUpdate();
315+
Delay_Init();
316+
317+
GPIO_InitTypeDef GPIO_InitStructure = {0};
318+
BLINKY_CLOCK_ENABLE;
319+
GPIO_InitStructure.GPIO_Pin = BLINKY_GPIO_PIN;
320+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
321+
GPIO_InitStructure.GPIO_Speed = %s;
322+
GPIO_Init(BLINKY_GPIO_PORT, &GPIO_InitStructure);
323+
324+
uint8_t ledState = 0;
325+
while (1) {
326+
GPIO_WriteBit(BLINKY_GPIO_PORT, BLINKY_GPIO_PIN, ledState);
327+
ledState ^= 1;
328+
Delay_Ms(1000);
329+
}
330+
return 0;
331+
}
332+
333+
void NMI_Handler(void) {}
334+
void HardFault_Handler(void)
335+
{
336+
while (1)
337+
{
338+
}
339+
}
340+
""" % (
341+
hdr,
342+
gpio_port,
343+
gpio_pin,
344+
gpio_clock_enable,
345+
"GPIO_Speed_30MHz" if is_v00Xx else "GPIO_Speed_50MHz"
346+
)
347+
else:
348+
is_ch56x = mcu.startswith("ch56")
349+
init_code = "SetSysClock(CLK_SOURCE_PLL_60MHz);" if not is_ch56x else "SystemInit(FREQ_SYS);\n Delay_Init(FREQ_SYS);"
350+
gpio_modecfg = "GPIO_Slowascent_PP_16mA" if is_ch56x else "GPIO_ModeOut_PP_20mA"
351+
main_content = """
352+
#include <%s>
353+
#define BLINKY_GPIO_PIN GPIO_Pin_8
354+
355+
int main(void)
356+
{
357+
%s
358+
GPIOA_SetBits(BLINKY_GPIO_PIN);
359+
GPIOA_ModeCfg(BLINKY_GPIO_PIN, %s);
360+
while(1) {
361+
DelayMs(1000);
362+
GPIOA_InverseBits(BLINKY_GPIO_PIN);
363+
}
364+
}
365+
""" % (
366+
hdr,
367+
init_code,
368+
gpio_modecfg
369+
)
370+
elif framework == "freertos":
371+
if not is_ch5x and not is_ch6x:
372+
main_content = """
373+
#include "debug.h"
374+
#include "FreeRTOS.h"
375+
#include "task.h"
376+
377+
TaskHandle_t example_task_handle;
378+
void example_task(void *pvParameters)
379+
{
380+
while (1)
381+
{
382+
printf("Hello FreeRTOS!\\n");
383+
vTaskDelay(250);
384+
}
385+
}
386+
387+
int main(void)
388+
{
389+
SystemCoreClockUpdate();
390+
Delay_Init();
391+
USART_Printf_Init(115200);
392+
xTaskCreate((TaskFunction_t)example_task,
393+
(const char *)"example",
394+
(uint16_t)256,
395+
(void *)NULL,
396+
(UBaseType_t)5,
397+
(TaskHandle_t *)&example_task_handle);
398+
vTaskStartScheduler();
399+
while (1)
400+
{
401+
printf("shouldn't run at here!!\\n");
402+
}
403+
}
404+
"""
405+
else:
406+
main_content = """
407+
#include "debug.h"
408+
#include "FreeRTOS.h"
409+
#include "task.h"
410+
411+
int main(void)
412+
{
413+
SystemCoreClockUpdate();
414+
Delay_Init();
415+
USART_Printf_Init(115200);
416+
vTaskStartScheduler();
417+
}
418+
"""
419+
additional_files.append((
420+
"FreeRTOSConfig.h",
421+
"""
422+
#ifndef FREERTOS_CONFIG_H
423+
#define FREERTOS_CONFIG_H
424+
#include "debug.h"
425+
426+
/*-----------------------------------------------------------
427+
* Application specific definitions.
428+
*
429+
* These definitions should be adjusted for your particular hardware and
430+
* application requirements.
431+
*
432+
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
433+
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
434+
*
435+
* See http://www.freertos.org/a00110.html.
436+
*----------------------------------------------------------*/
437+
438+
/* See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
439+
440+
/* don't have MTIME */
441+
#define configMTIME_BASE_ADDRESS ( 0 )
442+
#define configMTIMECMP_BASE_ADDRESS ( 0 )
443+
444+
#define configUSE_PREEMPTION 1
445+
#define configUSE_IDLE_HOOK 0
446+
#define configUSE_TICK_HOOK 0
447+
#define configCPU_CLOCK_HZ SystemCoreClock
448+
#define configTICK_RATE_HZ ( ( TickType_t ) 500 )
449+
#define configMAX_PRIORITIES ( 15 )
450+
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 256 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */
451+
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 12 * 1024 ) )
452+
#define configMAX_TASK_NAME_LEN ( 16 )
453+
#define configUSE_TRACE_FACILITY 0
454+
#define configUSE_16_BIT_TICKS 0
455+
#define configIDLE_SHOULD_YIELD 0
456+
#define configUSE_MUTEXES 1
457+
#define configQUEUE_REGISTRY_SIZE 8
458+
#define configCHECK_FOR_STACK_OVERFLOW 0
459+
#define configUSE_RECURSIVE_MUTEXES 1
460+
#define configUSE_MALLOC_FAILED_HOOK 0
461+
#define configUSE_APPLICATION_TASK_TAG 0
462+
#define configUSE_COUNTING_SEMAPHORES 1
463+
#define configGENERATE_RUN_TIME_STATS 0
464+
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
465+
466+
/* Co-routine definitions. */
467+
#define configUSE_CO_ROUTINES 0
468+
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
469+
470+
/* Software timer definitions. */
471+
#define configUSE_TIMERS 1
472+
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
473+
#define configTIMER_QUEUE_LENGTH 4
474+
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
475+
476+
477+
478+
/* Set the following definitions to 1 to include the API function, or zero
479+
to exclude the API function. */
480+
#define INCLUDE_vTaskPrioritySet 1
481+
#define INCLUDE_uxTaskPriorityGet 1
482+
#define INCLUDE_vTaskDelete 1
483+
#define INCLUDE_vTaskCleanUpResources 1
484+
#define INCLUDE_vTaskSuspend 1
485+
#define INCLUDE_vTaskDelayUntil 1
486+
#define INCLUDE_vTaskDelay 1
487+
#define INCLUDE_eTaskGetState 1
488+
#define INCLUDE_xTimerPendFunctionCall 1
489+
#define INCLUDE_xTaskAbortDelay 1
490+
#define INCLUDE_xTaskGetHandle 1
491+
#define INCLUDE_xSemaphoreGetMutexHolder 1
492+
493+
494+
/* Normal assert() semantics without relying on the provision of an assert.h
495+
header file. */
496+
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); printf("err at line %d of file \\"%s\\". \\r\\n ",__LINE__,__FILE__); while(1); }
497+
498+
/* Map to the platform printf function. */
499+
#define configPRINT_STRING( pcString ) printf( pcString )
500+
501+
502+
#endif /* FREERTOS_CONFIG_H */
503+
"""
504+
))
505+
else:
506+
raise NotImplementedError(
507+
"Sample code generation is not implemented for the '%s' framework" % framework
508+
)
509+
510+
src_dir = config.get("platformio", "src_dir")
511+
main_path = os.path.join(src_dir, "main.%s" % ("cpp" if is_cpp_project else "c"))
512+
if os.path.isfile(main_path):
513+
return None
514+
if not os.path.isdir(src_dir):
515+
os.makedirs(src_dir)
516+
with open(main_path, mode="w", encoding="utf8") as fp:
517+
fp.write(main_content.strip())
518+
for ap in additional_files:
519+
additional_file_path = os.path.join(src_dir, ap[0])
520+
with open(additional_file_path, mode="w", encoding="utf8") as fp:
521+
fp.write(ap[1].strip())
522+
return True

0 commit comments

Comments
 (0)