104|0

6

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第3期】任务汇总 [复制链接]

 

本贴是Follow me第二季第3期,所有任务的相关视频、任务内容、代码等内容的汇总帖。具体如下:

一、任务介绍

    本次Follow me第二季第3期的活动,主要的硬件环境就是RA的evb板子,具体型号为:EK-RA6M5开发套件。包含一个开发板,一条micro USB数据线,一条网线和一条micro USB转type A接口的数据线。

 

        本次活动主要参考ra官方的《ra-fsp-examples-5.6.0.example.2》示例程序,完成以下四个任务:

  • 入门任务:搭建环境,下载调试示例程序,Blink,按键
  • 基础任务:quad-spi flash和octo-spi flash配置及读写速度测试;DAC配置生成波形正弦波形
  • 进阶任务:示例程序中新增命令打印信息,输出DAC的实时数据
  • 扩展任务:设计一个类似信号发生器功能的例程。通过命令或按键,设置DAC输出波形,可通过flash存储历史波形等信息。

 

二、具体任务

1. 入门任务

  • 任务链接

        》》》【Follow me第二季第3期】 EK-RA6M5 入门任务 《《《

  • 流程图

 

  • 主要代码片段
    • 控制蓝灯blink的定时器回调函数
    void gpt_blue_callback(timer_callback_args_t * p_args)
    {
        /* Void the unused params */
        FSP_PARAMETER_NOT_USED(p_args);
    
        switch (s_blueled_flashing)
        {
            case ON:
            {
                if ((s_intense++ ) < s_duty)
                {
                    TURN_BLUE_ON
                }
                else
                {
                    TURN_BLUE_OFF
                }
    
                if (s_intense >= 100)
                {
                    s_intense = 0;
                    s_duty = g_pwm_dcs[g_board_status.led_intensity];
                }
                break;
            }
            default:
            {
                TURN_BLUE_OFF
                s_intense = 0;
                s_duty = g_pwm_dcs[g_board_status.led_intensity];
            }
        }
    }
  • 按键控制闪灯亮度的回调函数
void button_irq10_callback(external_irq_callback_args_t *p_args)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    BaseType_t xResult = pdFAIL;
    EventBits_t uxBits;

    /* Void the unused args */
    FSP_PARAMETER_NOT_USED(p_args);

    uxBits = xEventGroupGetBitsFromISR (g_update_console_event);

    if ((uxBits & (STATUS_UPDATE_INTENSE_INFO)) != (STATUS_UPDATE_INTENSE_INFO))
    {
        /* Cast, as compiler will assume calc is int */
        g_board_status.led_intensity = (uint16_t) ((g_board_status.led_intensity + 1) % 4);
        xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_INTENSE_INFO,
                                            &xHigherPriorityTaskWoken);

        /* Was the message posted successfully? */
        if (pdFAIL != xResult)
        {
            /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
             switch should be requested.  The macro used is port specific and will
             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
             the documentation page for the port being used. */
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
    }
}
  • 按键控制闪灯频率的回调函数
void button_irq9_callback(external_irq_callback_args_t *p_args)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    BaseType_t xResult = pdFAIL;
    EventBits_t uxBits;

    /* Void the unused args */
    FSP_PARAMETER_NOT_USED(p_args);

    uxBits = xEventGroupGetBitsFromISR (g_update_console_event);

    if ((uxBits & (STATUS_UPDATE_FREQ_INFO)) != (STATUS_UPDATE_FREQ_INFO))
    {
        /* Cast, as compiler will assume calc is int */
        g_board_status.led_frequency = (uint16_t) ((g_board_status.led_frequency + 1) % 4);
        xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_UPDATE_FREQ_INFO, &xHigherPriorityTaskWoken);

        /* Was the message posted successfully? */
        if (pdFAIL != xResult)
        {
            /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
             switch should be requested.  The macro used is port specific and will
             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
             the documentation page for the port being used. */
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
    }
}
  • 设备运行结果

  

 

2. 基础任务

  • 任务链接

        》》》【Follow me第二季第3期】基础任务 《《《

  • 流程图

  FLASH读写速度测试

  DAC波形输出

 

  • 主要代码片段

        2.1 OSPI写测试

static uint32_t write_dopi_ospi(uint32_t data_size)
{

    fsp_err_t err;
    uint32_t test_var;

    /* Cast to req type */
    uint8_t * p_dest = (uint8_t *)OSPI_DMA_ADDRESS;
    timer_status_t status = {};
    uint32_t number_of_pages;

    R_GPT_Open(g_memory_performance.p_ctrl, g_memory_performance.p_cfg);

    /* Cast, as compiler will assume result of calc to be int */
    number_of_pages = (uint32_t)(data_size * (1024 / OSPI_TEST_PAGE_SIZE));

    /* Write 32 blocks worth of data starting at Block 0
     * Block size = 64K, i.e. 2 blocks = 128K of data
     * check this comment....... */


    for (test_var = 0; test_var < number_of_pages; test_var++ )
    {
    /* Performance measured around this loop will be slightly lower due to branches and test write-in-progress
         * The actual throughput should be measured with direct debugger downloads (not supported by SEGGER yet)*/

        R_GPT_Start(g_memory_performance.p_ctrl);
        err = R_OSPI_Write(g_ospi.p_ctrl, s_page, p_dest, OSPI_TEST_PAGE_SIZE);
        if (FSP_SUCCESS != err)
        {
            __asm("bkpt");
        }
        ospi_test_wait_until_wip();
        p_dest += OSPI_TEST_PAGE_SIZE;
        R_GPT_Stop(g_memory_performance.p_ctrl);
        vTaskDelay(1U);
    }

    R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
    R_GPT_Reset(g_memory_performance.p_ctrl);
    R_GPT_Close(g_memory_performance.p_ctrl);

    return (status.counter);
}

    2.2 OSPI 读测试

static uint32_t read_dopi_ospi(uint32_t data_size)
{
    /* Cast to req type */
    uint32_t * p_src = (uint32_t *)OSPI_DMA_ADDRESS;

    /* Cast to req type */
    uint32_t * p_dest = (uint32_t *)s_perf_read;

    /* Full bus access, transfer 4 bytes at a time */
    timer_status_t status = {};

    R_GPT_Open(g_memory_performance.p_ctrl, g_memory_performance.p_cfg);

#ifdef READ_PAGE_BY_PAGE

    /* convert to number of mem pages */
    number_of_blocks = data_size * ( 1024 / OSPI_TEST_PAGE_SIZE);

    while(number_of_blocks--)
    {
        /* convert page size to number of 32bit reads */
        data = (OSPI_TEST_PAGE_SIZE) / 4U;

        /* Start timer */
        R_GPT_Start(g_memory_performance.p_ctrl);

#ifdef MANUAL_READ
        while (data)
        {
            *p_dest = *p_src;
            p_dest++;
            p_src++;
            data--;
        }
#endif

#define READ_MEMCPY
#ifdef READ_MEMCPY
        memcpy ( p_dest, p_src, OSPI_TEST_PAGE_SIZE / 4);
        p_src += OSPI_TEST_PAGE_SIZE / 4;
        p_dest += OSPI_TEST_PAGE_SIZE / 4;

        /* Stop timer */
        R_GPT_Stop(g_memory_performance.p_ctrl);
        vTaskDelay(1U);
#endif

    }
#endif /* READ_PAGE_BY_PAGE */

#ifdef READ_AS_SINGLE_BLOCK
    /* Start timer */
    R_GPT_Start(g_memory_performance.p_ctrl);

    R_OSPI_XipEnter(g_ospi.p_ctrl);
        memcpy (p_dest, p_src, (data_size * 1024) / 4);
    R_OSPI_XipExit(g_ospi.p_ctrl);

    /* Stop timer */
    R_GPT_Stop(g_memory_performance.p_ctrl);
#endif

    R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
    R_GPT_Reset(g_memory_performance.p_ctrl);
    R_GPT_Close(g_memory_performance.p_ctrl);

    return (status.counter);
}

    2.3 QSPI写测试

static uint32_t qspi_write_test(uint32_t block_size)
{
    fsp_err_t fsp_err;
    uint32_t qspi_write_result = 0;
    timer_status_t status = {};
    fsp_err_t err = FSP_SUCCESS;
    spi_flash_protocol_t current_spi_mode;

    /* Convert from kB */
    block_size *= 1024;

    /* The comms mode is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    uint32_t page_write_count = 0;
    uint8_t  * p_mem_addr;

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    while (((page_write_count * SECTOR_SIZE) < block_size)
        && ( FSP_SUCCESS == err ) )
    {

        /* Erase Flash for one sector */
        err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
        if (FSP_SUCCESS != err)
        {
            sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
        }
        else
        {
            err = get_flash_status();
            if (FSP_SUCCESS != err)
            {
                sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
            }

            /* Verify the erased block data */
            uint32_t count;
            for (count = 0; count < SECTOR_SIZE; count++ )
            {
                if (DEFAULT_MEM_VAL != p_mem_addr[count])
                {
                    /* Verification failed, perhaps the ERASE failed */
                    err = FSP_ERR_NOT_ERASED;
                }
            }
        }

        p_mem_addr += SECTOR_SIZE;
        page_write_count++;
    }

    /* Start the test timer */
    fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
    page_write_count = 0;

    while (((page_write_count * PAGE_WRITE_SIZE) < block_size)
        && (FSP_SUCCESS == err))
    {
        if (FSP_SUCCESS == err)
        {
            /* Write data to QSPI Flash */
            /* Each block begins one character shifted along the source text. To avoid regular striping in memory */
            err = R_QSPI_Write(&g_qspi_ctrl, &(sp_source[page_write_count]), p_mem_addr, PAGE_WRITE_SIZE);
            if (FSP_SUCCESS != err)
            {
                sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
            }
            else
            {
                err = get_flash_status();
                if (FSP_SUCCESS != err)
                {
                    sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
                }
            }
        }
        p_mem_addr += PAGE_WRITE_SIZE;
        page_write_count++;
    }

    /* close QSPI module */
    deinit_qspi(current_spi_mode);

    fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    qspi_write_result = status.counter;

    return (qspi_write_result);
}

    2.4 QSPI读测试

static uint32_t qspi_read_test(uint32_t block_size)
{
    fsp_err_t fsp_err;
    fsp_err_t err = FSP_SUCCESS;

    uint32_t qspi_read_result = 0;
    timer_status_t status = {};
    spi_flash_protocol_t current_spi_mode;

    uint8_t  * p_dma_read_buffer;
    uint32_t   page_read_count;
    uint8_t  * p_mem_addr;

    /* Convert from kB */
    block_size *= 1024;

    p_dma_read_buffer = pvPortMalloc(block_size);

    if (NULL == p_dma_read_buffer)
    {
        HeapStats_t pxHeapStats;
        vPortGetHeapStats(&pxHeapStats);

        sprintf(s_print_buffer, "\r\nQSPI malloc operation Failed - Max free mem: %dbytes\r\n",
                pxHeapStats.xSizeOfLargestFreeBlockInBytes);

        /* Verification failed, perhaps the ERASE failed */
        err = FSP_ERR_NOT_ERASED;
    }

    /* The comms mode of the FLASH device is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    /* Start the test timer */
    fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    page_read_count = 0;

    /* cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    while (((page_read_count * PAGE_WRITE_SIZE) < block_size)
            && (FSP_SUCCESS == err))
    {
        /* Verify the written data */
        /* Each block begins one character shifted along the source text. To avoid regular striping in memory */
        if ((fsp_err_t) (memcmp (p_mem_addr, &(sp_source[page_read_count]), PAGE_WRITE_SIZE)) != FSP_SUCCESS)
        {
            err = FSP_ERR_NOT_ERASED;

            sprintf(s_print_buffer, "\r\nQSPI operation Failed -> Data read does not match with written data\r\n");
        }
        p_mem_addr += PAGE_WRITE_SIZE;
        page_read_count++;
    }

    fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);

    /* close QSPI module */
    deinit_qspi(current_spi_mode);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);

    /* Handle error */
    if (FSP_SUCCESS != fsp_err)
    {
        /* Fatal error */
        SYSTEM_ERROR
    }

    qspi_read_result = status.counter;

    vPortFree(p_dma_read_buffer);

    return (qspi_read_result);
}

    2.5 DAC波形输出


fsp_err_t common_init(void)
{
    fsp_err_t fsp_err = FSP_SUCCESS;

    fsp_err = adc_initialize ();
    if (FSP_SUCCESS != fsp_err)
    {
        return fsp_err;
    }

    // DAC初始化
    fsp_err = R_DAC_Open(&g_dac0_ctrl, &g_dac0_cfg);
    if (FSP_SUCCESS != fsp_err)
    {
        return fsp_err;
    }
    // DAC启动
    fsp_err = R_DAC_Start(&g_dac0_ctrl);
    if (FSP_SUCCESS != fsp_err)
    {
        return fsp_err;
    }

    fsp_err = icu_initialize ();
    if (FSP_SUCCESS != fsp_err)
    {
        return fsp_err;
    }

    fsp_err = gpt_initialize ();
#if 1

    if (FSP_SUCCESS != fsp_err)
    {
        return fsp_err;
    }

    led_duty_cycle_update ();
#endif

    /* Set baseline LED status */
    g_board_status.led_intensity = 0;
    g_board_status.led_frequency = 0;

    R_GPT_PeriodSet(g_blinker.p_ctrl, g_pwm_rates[g_board_status.led_frequency]);

    led_duty_cycle_update ();
    s_duty = g_pwm_dcs[g_board_status.led_intensity];

    /* Start the timers */
    R_GPT_Start(g_blinker.p_ctrl);
    R_GPT_Start(g_gpt_blue.p_ctrl);

    return fsp_err;
}

   

void gpt_blinker_callback(timer_callback_args_t *p_args)
{
    /* Void the unused params */
    FSP_PARAMETER_NOT_USED(p_args);

    // 计算正弦波
    uint16_t dac_val = 0;
    static double position = 0.0;
    position += (PI / 30); // add 6° per cycle

    if (position >= PI*2) // if angle bigger than 90°
        position = 0.0;

    dac_val = (uint16_t)((sin(position) + 1) / 2 * 4095);

    // 通过DAC输出正弦波
    R_DAC_Write(&g_dac0_ctrl, dac_val);


    if (OFF == s_blueled_flashing)
    {
        s_blueled_flashing = ON;

    }
    else
    {
        s_blueled_flashing = OFF;

    }
}
  • 设备运行结果

   

 

3. 进阶任务

  • 任务链接

        》》》【Follow me第二季第3期】进阶任务《《《

  • 流程图

 

  • 主要代码片段
test_fn dac_display_menu(void)
{
    int8_t c = -1;
    uint16_t wn_mcu_temp_f = 0;
    uint16_t fr_mcu_temp_f = 0;
    uint16_t wn_mcu_temp_c = 0;
    uint16_t fr_mcu_temp_c = 0;

    sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    sprintf (s_print_buffer, MODULE_NAME, g_selected_menu);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    wn_mcu_temp_f = g_board_status.temperature_f.whole_number;
    fr_mcu_temp_f = g_board_status.temperature_f.mantissa;
    wn_mcu_temp_c = g_board_status.temperature_c.whole_number;
    fr_mcu_temp_c = g_board_status.temperature_c.mantissa;

    sprintf (s_print_buffer, SUB_OPTIONS, FULL_NAME,
            wn_mcu_temp_f, fr_mcu_temp_f, wn_mcu_temp_c, fr_mcu_temp_c,
            g_dac_val);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);
    sprintf (s_print_buffer, MENU_RETURN_INFO);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    /* provide small delay so board_status should be up to date */
    vTaskDelay (s_ticks_to_wait);
    xEventGroupSetBits (g_update_console_event, STATUS_DAC_MONITOR);

}
  • 设备运行结果

  

 

 

4. 扩展任务

  • 任务链接

        》》》【Follow me第二季第3期】扩展任务《《《

  • 流程图

 

  • 主要代码片段

命令行菜单

test_fn dac_display_menu(void)
{
    int8_t c = -1;
    uint16_t wn_mcu_temp_f = 0;
    uint16_t fr_mcu_temp_f = 0;
    uint16_t wn_mcu_temp_c = 0;
    uint16_t fr_mcu_temp_c = 0;

    sprintf (s_print_buffer, "%s%s", gp_clear_screen, gp_cursor_home);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    sprintf (s_print_buffer, MODULE_NAME, g_selected_menu);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    wn_mcu_temp_f = g_board_status.temperature_f.whole_number;
    fr_mcu_temp_f = g_board_status.temperature_f.mantissa;
    wn_mcu_temp_c = g_board_status.temperature_c.whole_number;
    fr_mcu_temp_c = g_board_status.temperature_c.mantissa;

    sprintf (s_print_buffer, SUB_OPTIONS, FULL_NAME,
            wn_mcu_temp_f, fr_mcu_temp_f, wn_mcu_temp_c, fr_mcu_temp_c,
            g_dac_val);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);
    sprintf (s_print_buffer, MENU_RETURN_INFO);

    /* ignoring -Wpointer-sign is OK when treating signed char_t array as as unsigned */
    print_to_console((void*)s_print_buffer);

    /* provide small delay so board_status should be up to date */
    vTaskDelay (s_ticks_to_wait);
    xEventGroupSetBits (g_update_console_event, STATUS_DAC_MONITOR);


    uint32_t read_data_len = 0;
    uint32_t save_len = 0;
    while (CONNECTION_ABORT_CRTL != c)
    {
        c = input_from_console ();
        if ((MENU_EXIT_CRTL == c) || (CONNECTION_ABORT_CRTL == c))
        {
            break;
        }
        else if ('s' == c)
        {
            g_dac_write_data_len = 0;
            sprintf (s_print_buffer, "%s select: %c start save wave %s", gp_cursor_store, c, gp_cursor_restore);
            print_to_console((void*)s_print_buffer);
        }
        else if ('t' == c)
        {
            int offset =  sprintf (s_print_buffer, "%s select: %c stop save wave. \r\nsave data: \r\n\t", gp_cursor_store, c);
            save_len = g_dac_write_data_len;
            for (uint16_t i = 0; i < save_len; i++)
            {
                offset += sprintf (s_print_buffer + offset, "%d ", g_dac_adwrite_data_buff[i]);
            }
            sprintf (s_print_buffer + offset, " %s", gp_cursor_restore);
            print_to_console((void*)s_print_buffer);
            qspi_write(save_len * sizeof(uint16_t), g_dac_adwrite_data_buff);
        }
        else if ('p' == c)
        {
            sprintf (s_print_buffer, "%s select: %c get wave %s", gp_cursor_store, c, gp_cursor_restore);
            print_to_console((void*)s_print_buffer);
            qspi_read(&read_data_len, read_data_buff);
            int offset = sprintf (s_print_buffer, "get %s length: %d \r\nGet data: \r\n\t", gp_cursor_store, read_data_len/2);
            for (uint16_t i = 0; i < read_data_len / 2; i++)
            {
                offset += sprintf (s_print_buffer + offset, "%d ", read_data_buff[i]);
            }
            sprintf (s_print_buffer + offset, " %s", gp_cursor_restore);

            print_to_console((void*)s_print_buffer);
        }
    }


    xEventGroupClearBits (g_update_console_event, STATUS_DAC_MONITOR);
    return (0);
}

缓存DAC值

void gpt_blinker_callback(timer_callback_args_t *p_args)
{
    /* Void the unused params */
    FSP_PARAMETER_NOT_USED(p_args);

    uint16_t dac_val = 0;
    static double position = 0.0;
    position += (PI / 30); // add 6° per cycle

    if (position >= PI*2) // if angle bigger than 90°
        position = 0.0;

    dac_val = (uint16_t)((sin(position) + 1) / 2 * 4095);
    R_DAC_Write(&g_dac0_ctrl, dac_val);


    if (OFF == s_blueled_flashing)
    {
        s_blueled_flashing = ON;

    }
    else
    {
        s_blueled_flashing = OFF;

    }

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    BaseType_t xResult = pdFAIL;

    if (g_dac_val != dac_val)
    {
        g_dac_val = dac_val;
        /* Cast, as compiler will assume calc is int */
        xResult = xEventGroupSetBitsFromISR(g_update_console_event, STATUS_DAC_OUTPUT_VAL, &xHigherPriorityTaskWoken);
        /* Was the message posted successfully? */
        if (pdFAIL != xResult)
        {
            /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
             switch should be requested.  The macro used is port specific and will
             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
             the documentation page for the port being used. */
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
        g_dac_write_data_len = g_dac_write_data_len >= MAX_DAC_WRITE_BUFFER ? 0 : g_dac_write_data_len;

        // save new data to buffer
        g_dac_adwrite_data_buff[g_dac_write_data_len++] = g_dac_val;
    }
}

SPI Flash写入

static uint32_t qspi_write(uint32_t data_size, uint8_t* data)
{
#if 0
    fsp_err_t fsp_err;
    uint32_t qspi_write_result = 0;
    timer_status_t status = {};
    fsp_err_t err = FSP_SUCCESS;
    spi_flash_protocol_t current_spi_mode;

    /* The comms mode is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    uint8_t  * p_mem_addr;

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    /* Erase Flash for one sector */
    err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
    if (FSP_SUCCESS != err)
    {
        sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
    }

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    /* Write data to QSPI Flash */
    /* Each block begins one character shifted along the source text. To avoid regular striping in memory */
    err = R_QSPI_Write(&g_qspi_ctrl, (uint8_t*)&data_size, p_mem_addr, PAGE_WRITE_SIZE);
    if (FSP_SUCCESS != err)
    {
        sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
    }

    /* close QSPI module */
    deinit_qspi(current_spi_mode);

    qspi_write_result = status.counter;

    return (qspi_write_result);
#else
    fsp_err_t fsp_err;
    uint32_t qspi_write_result = 0;
    timer_status_t status = {};
    fsp_err_t err = FSP_SUCCESS;
    spi_flash_protocol_t current_spi_mode;

    if (data == NULL)
    {
        err = FSP_ERR_NOT_ERASED;
        return err;
    }

    /* Convert from kB */
    uint32_t block_size = (data_size / 1024 + 1)*1024;

    uint8_t* p_dma_read_buffer = pvPortMalloc(block_size);
    if (NULL == p_dma_read_buffer)
    {
        HeapStats_t pxHeapStats;
        vPortGetHeapStats(&pxHeapStats);

        sprintf(s_print_buffer, "\r\nQSPI malloc operation Failed - Max free mem: %dbytes\r\n",
                pxHeapStats.xSizeOfLargestFreeBlockInBytes);

        /* Verification failed, perhaps the ERASE failed */
        err = FSP_ERR_NOT_ERASED;
    }

    memcpy(p_dma_read_buffer, &data_size, sizeof(data_size));
    memcpy(p_dma_read_buffer + sizeof(data_size), data, data_size);

    /* The comms mode is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    uint32_t page_write_count = 0;
    uint8_t  * p_mem_addr;

    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    while (((page_write_count * SECTOR_SIZE) < block_size)
        && ( FSP_SUCCESS == err ) )
    {

        /* Erase Flash for one sector */
        err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
        if (FSP_SUCCESS != err)
        {
            sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
        }
        else
        {
            err = get_flash_status();
            if (FSP_SUCCESS != err)
            {
                sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
            }

            /* Verify the erased block data */
            uint32_t count;
            for (count = 0; count < SECTOR_SIZE; count++ )
            {
                if (DEFAULT_MEM_VAL != p_mem_addr[count])
                {
                    /* Verification failed, perhaps the ERASE failed */
                    err = FSP_ERR_NOT_ERASED;
                }
            }
        }

        p_mem_addr += SECTOR_SIZE;
        page_write_count++;
    }


    /* Cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
    page_write_count = 0;

    while (((page_write_count * PAGE_WRITE_SIZE) < block_size)
        && (FSP_SUCCESS == err))
    {
        if (FSP_SUCCESS == err)
        {
            /* Write data to QSPI Flash */
            /* Each block begins one character shifted along the source text. To avoid regular striping in memory */
//            err = R_QSPI_Write(&g_qspi_ctrl, &(qspi_source[page_write_count]), p_mem_addr, PAGE_WRITE_SIZE);
            err = R_QSPI_Write(&g_qspi_ctrl, &(p_dma_read_buffer[page_write_count]), p_mem_addr, PAGE_WRITE_SIZE);
            if (FSP_SUCCESS != err)
            {
                sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
            }
            else
            {
                err = get_flash_status();
                if (FSP_SUCCESS != err)
                {
                    sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
                }
            }
        }
        p_mem_addr += PAGE_WRITE_SIZE;
        page_write_count++;
    }

    /* close QSPI module */
    deinit_qspi(current_spi_mode);

    qspi_write_result = status.counter;

    vPortFree(p_dma_read_buffer);

    return (qspi_write_result);

#endif
}

SPI Flash读取

static uint32_t qspi_read(uint32_t* data_size, uint8_t* data)
{
#if 0
    fsp_err_t fsp_err;
    fsp_err_t err = FSP_SUCCESS;

    uint32_t qspi_read_result = 0;
    timer_status_t status = {};
    spi_flash_protocol_t current_spi_mode;

    uint8_t  * p_mem_addr;

    /* The comms mode of the FLASH device is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    /* cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    memcpy(data_size, p_mem_addr, 1);
    sprintf(s_print_buffer, "save length: %d", *data_size);
    print_to_console((void*)s_print_buffer);

    /* close QSPI module */
    deinit_qspi(current_spi_mode);

    qspi_read_result = status.counter;

    return (qspi_read_result);
#else
    fsp_err_t fsp_err;
    fsp_err_t err = FSP_SUCCESS;

    uint32_t qspi_read_result = 0;
    timer_status_t status = {};
    spi_flash_protocol_t current_spi_mode;

    uint8_t  * p_dma_read_buffer;
    uint32_t   page_read_count;
    uint8_t  * p_mem_addr;

    /* Convert from kB */
    uint32_t block_size = 2*1024;

    p_dma_read_buffer = pvPortMalloc(block_size);

    if (NULL == p_dma_read_buffer)
    {
        HeapStats_t pxHeapStats;
        vPortGetHeapStats(&pxHeapStats);

        sprintf(s_print_buffer, "\r\nQSPI malloc operation Failed - Max free mem: %dbytes\r\n",
                pxHeapStats.xSizeOfLargestFreeBlockInBytes);

        /* Verification failed, perhaps the ERASE failed */
        err = FSP_ERR_NOT_ERASED;
    }

    /* The comms mode of the FLASH device is EXTENDED_SPI by default */
    current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;

    /* initialise the QSPI, and change mode to that set in FSP */
    err = qpi_init();
    if (FSP_SUCCESS == err)
    {
        /* The comms mode has changed. So if recovering, this new mode required */
        current_spi_mode = g_qspi_cfg.spi_protocol;
    }

    page_read_count = 0;

    /* cast to req type */
    p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;

    *data_size = *((uint32_t*)p_mem_addr);
    memcpy(data, p_mem_addr + 4, *data_size);

    while (((page_read_count * PAGE_WRITE_SIZE) < block_size)
            && (FSP_SUCCESS == err))
    {
        /* Verify the written data */
        /* Each block begins one character shifted along the source text. To avoid regular striping in memory */
        if ((fsp_err_t) (memcmp (p_mem_addr, &(qspi_source[page_read_count]), PAGE_WRITE_SIZE)) != FSP_SUCCESS)
        {
            err = FSP_ERR_NOT_ERASED;

            sprintf(s_print_buffer, "\r\nQSPI operation Failed -> Data read does not match with written data\r\n");
        }
        p_mem_addr += PAGE_WRITE_SIZE;
        page_read_count++;
    }

    qspi_read_result = status.counter;

    vPortFree(p_dma_read_buffer);

    return (qspi_read_result);
#endif
}
  • 设备运行结果

 

 

 

 

三、任务视频

》》》视频链接《《《

 

四、任务代码

》》》示例代码链接《《《

 

五、活动心得

        很高兴能够参加本次的活动,最近工作比较忙,拖到最后完成了各个任务。这个开发板资源还是非常的丰富,然后SDK的demo也比较完善,很多值得学习的地方。后续再项目应用中也尝试使用RA系列的芯片。同时也会更过关注这个RA低功耗一些相关的MCU上面。

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表