@@ -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