mirror of
https://github.com/cwyark/ameba-sdk-gcc-make.git
synced 2025-07-31 20:31:07 +00:00
first commit and add gitignore, README.md
This commit is contained in:
commit
760756ba2c
1861 changed files with 709236 additions and 0 deletions
2733
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.ewd
Executable file
2733
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.ewd
Executable file
File diff suppressed because it is too large
Load diff
2040
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.ewp
Executable file
2040
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.ewp
Executable file
File diff suppressed because it is too large
Load diff
10
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.eww
Executable file
10
project/realtek_ameba1_va0_example/EWARM-RELEASE/Project.eww
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\Project.ewp</path>
|
||||
</project>
|
||||
<batchBuild/>
|
||||
</workspace>
|
||||
|
||||
|
||||
203
project/realtek_ameba1_va0_example/EWARM-RELEASE/image2.icf
Executable file
203
project/realtek_ameba1_va0_example/EWARM-RELEASE/image2.icf
Executable file
|
|
@ -0,0 +1,203 @@
|
|||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
//define symbol __ICFEDIT_intvec_start__ = 0x00000000;
|
||||
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x000FFFFF;
|
||||
define symbol __ICFEDIT_region_TCM_start__ = 0x1FFF0000;
|
||||
define symbol __ICFEDIT_region_TCM_end__ = 0x1FFFFFFF;
|
||||
define symbol __ICFEDIT_region_ROM_USED_RAM_start__ = 0x10000000;
|
||||
define symbol __ICFEDIT_region_ROM_USED_RAM_end__ = 0x10005FFF;
|
||||
//define symbol __ICFEDIT_region_RECY_RAM_start__ = 0x10002090;
|
||||
//define symbol __ICFEDIT_region_RECY_RAM_end__ = 0x100037FF;
|
||||
define symbol __ICFEDIT_region_BD_RAM_start__ = 0x10006000;
|
||||
define symbol __ICFEDIT_region_BD_RAM_end__ = 0x1006FFFF;
|
||||
define symbol __ICFEDIT_region_SDRAM_RAM_start__ = 0x30000000;
|
||||
define symbol __ICFEDIT_region_SDRAM_RAM_end__ = 0x301FFFFF;
|
||||
|
||||
/*-Sizes-*/
|
||||
/*define symbol __ICFEDIT_size_cstack__ = 0x400;*/
|
||||
/*define symbol __ICFEDIT_size_heap__ = 0x800;*/
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region TCM_region = mem:[from __ICFEDIT_region_TCM_start__ to __ICFEDIT_region_TCM_end__];
|
||||
define region ROM_USED_RAM_region = mem:[from __ICFEDIT_region_ROM_USED_RAM_start__ to __ICFEDIT_region_ROM_USED_RAM_end__];
|
||||
//define region RECY_RAM_region = mem:[from __ICFEDIT_region_RECY_RAM_start__ to __ICFEDIT_region_RECY_RAM_end__];
|
||||
define region BD_RAM_region = mem:[from __ICFEDIT_region_BD_RAM_start__ to __ICFEDIT_region_BD_RAM_end__];
|
||||
define region SDRAM_RAM_region = mem:[from __ICFEDIT_region_SDRAM_RAM_start__ to __ICFEDIT_region_SDRAM_RAM_end__];
|
||||
|
||||
/*define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };*/
|
||||
/*define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };*/
|
||||
|
||||
//initialize by copy { readwrite };
|
||||
//initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application
|
||||
|
||||
//do not initialize { section * };
|
||||
|
||||
//place at address mem:__ICFEDIT_intvec_start__ { readonly section .vectors_table };
|
||||
|
||||
|
||||
/*place in RAM_region { readwrite, block CSTACK, block HEAP };*/
|
||||
place in TCM_region { readwrite };
|
||||
|
||||
/****************************************
|
||||
* ROM Section config *
|
||||
****************************************/
|
||||
keep { section .rom };
|
||||
place at start of ROM_region { readonly, section .rom };
|
||||
|
||||
/****************************************
|
||||
* BD RAM Section config *
|
||||
****************************************/
|
||||
keep { section .ram_dedecated_vector_table* };
|
||||
define block .vector_table with fixed order{section .ram_dedecated_vector_table*};
|
||||
|
||||
keep { section .ram_user_define_irq_table* };
|
||||
define block .user_vector_table with fixed order{section .ram_user_define_irq_table*};
|
||||
|
||||
keep { section .ram_user_define_data_table* };
|
||||
define block .user_data_table with fixed order{section .ram_user_define_data_table*};
|
||||
|
||||
define block .rom.bss with fixed order{ section .hal.ram.bss* object hal_misc.o,
|
||||
section .hal.ram.bss* object hal_pinmux.o,
|
||||
section .hal.ram.bss* object diag.o,
|
||||
section .hal.ram.bss* object rtl8195a_ssi_rom.o,
|
||||
section .hal.ram.bss* object rtl8195a_gpio.o,
|
||||
section .hal.ram.bss*,
|
||||
section .timer2_7_vector_table.data*,
|
||||
section .infra.ram.bss*,
|
||||
section .mon.ram.bss*,
|
||||
section .wlan_ram_map* object rom_wlan_ram_map.o,
|
||||
section .wlan_ram_map*,
|
||||
section .libc.ram.bss*,
|
||||
};
|
||||
|
||||
keep { section .start.ram.data* };
|
||||
define block .ram.start.table with fixed order{ section .start.ram.data* };
|
||||
|
||||
keep { section .image1.validate.rodata* };
|
||||
keep { section .infra.ram.data* };
|
||||
keep { section .timer.ram.data* };
|
||||
keep { section .hal.ram.data* };
|
||||
define block .ram_image1.data with fixed order{ section .image1.validate.rodata*,
|
||||
section .infra.ram.data*,
|
||||
section .timer.ram.data*,
|
||||
section .cutb.ram.data*,
|
||||
section .hal.ram.data* object rom.o, // for standard libaray __impure_data_ptr
|
||||
section .cutc.ram.data*,
|
||||
section .hal.ram.data*
|
||||
};
|
||||
define block .ram_image1.bss with fixed order{ //section .hal.flash.data*,
|
||||
section .hal.sdrc.data*
|
||||
};
|
||||
|
||||
define block .ram_image1.text with fixed order{ section .hal.ram.text*,
|
||||
section .hal.sdrc.text*,
|
||||
//section .text* object startup.o,
|
||||
section .infra.ram.text*,
|
||||
};
|
||||
|
||||
define block IMAGE1 with fixed order { section LOADER };
|
||||
define block IMAGE1_DBG with fixed order { block .ram.start.table, block .ram_image1.data, block .ram_image1.bss, block .ram_image1.text };
|
||||
|
||||
place at start of ROM_USED_RAM_region { readwrite,
|
||||
block .vector_table,
|
||||
block .user_vector_table,
|
||||
block .user_data_table,
|
||||
block .rom.bss,
|
||||
block IMAGE1
|
||||
};
|
||||
|
||||
keep { section .image2.ram.data* };
|
||||
define block .image2.start.table1 with fixed order{ section .image2.ram.data* };
|
||||
|
||||
keep { section .image2.validate.rodata*, section .custom.validate.rodata* };
|
||||
define block .image2.start.table2 with fixed order{ section .image2.validate.rodata*, section .custom.validate.rodata* };
|
||||
|
||||
define block SHT$$PREINIT_ARRAY { preinit_array };
|
||||
define block SHT$$INIT_ARRAY { init_array };
|
||||
define block CPP_INIT with fixed order { block SHT$$PREINIT_ARRAY,
|
||||
block SHT$$INIT_ARRAY };
|
||||
|
||||
define block .ram_image2.text with fixed order{ section .infra.ram.start*,
|
||||
section .rodata*,
|
||||
block CPP_INIT,
|
||||
section .mon.ram.text*,
|
||||
section .hal.flash.text*,
|
||||
section .hal.gpio.text*,
|
||||
section .text* object main.o,
|
||||
section .text*,
|
||||
section CODE,
|
||||
section .otg.rom.text,
|
||||
section Veneer object startup.o,
|
||||
section __DLIB_PERTHREAD,
|
||||
//section .mdns.text
|
||||
};
|
||||
|
||||
define block .ram.data with fixed order{ section .data*,
|
||||
section DATA,
|
||||
section .ram.otg.data.a,
|
||||
section .iar.init_table,
|
||||
//section .mdns.data
|
||||
};
|
||||
|
||||
define block IMAGE2 with fixed order { block .image2.start.table1, block .image2.start.table2, block .ram_image2.text, block .ram.data };
|
||||
|
||||
define block .ram.bss with fixed order{ section .bss*,
|
||||
section .ssl_ram_map,
|
||||
section .hal.flash.data*,
|
||||
section .hal.gpio.data*,
|
||||
section COMMON,
|
||||
section .bdsram.data*,
|
||||
section .bss* object heap_4.o
|
||||
};
|
||||
define block .bf_data with fixed order{ section .bfsram.data* };
|
||||
define block .heap with fixed order{ section .heap* };
|
||||
define block .stack_dummy with fixed order { section .stack };
|
||||
place at start of BD_RAM_region { readwrite,
|
||||
block IMAGE2,
|
||||
//block IMAGE1_DBG,
|
||||
block .ram.bss,
|
||||
//block .bf_data,
|
||||
};
|
||||
|
||||
//place at address mem:0x10052b00 { readwrite,
|
||||
place at end of BD_RAM_region { readwrite,
|
||||
block .bf_data,
|
||||
};
|
||||
|
||||
define block SDRAM with fixed order{ section .sdram.text*,
|
||||
section .sdram.data*,
|
||||
section .mdns.text*,
|
||||
section .mdns.data*
|
||||
};
|
||||
place at start of SDRAM_RAM_region { readwrite,
|
||||
block SDRAM,
|
||||
//block IMAGE1_DBG
|
||||
};
|
||||
|
||||
|
||||
/* TCM placement */
|
||||
define overlay TCM_overlay { section .tcm.heap,
|
||||
section .bss object mem.o,
|
||||
section .bss object memp.o,
|
||||
block .heap,
|
||||
block .stack_dummy
|
||||
};
|
||||
/* dummy code placement */
|
||||
define overlay TCM_overlay { block IMAGE1_DBG };
|
||||
place at start of TCM_region { readwrite,
|
||||
overlay TCM_overlay
|
||||
};
|
||||
|
||||
define exported symbol __rom_bss_start__ = 0x10000300; // use in rom
|
||||
define exported symbol __rom_bss_end__ = 0x10000bc8; // use in rom
|
||||
define exported symbol __ram_start_table_start__= 0x10000bc8; // use in rom
|
||||
define exported symbol __image1_validate_code__= 0x10000bdc; // needed by ram code
|
||||
define exported symbol _rtl_impure_ptr = 0x10001c60; // for standard library
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use ADC.
|
||||
|
||||
|
||||
1.Prepare a DC power supply to provide a adjustable voltage.
|
||||
|
||||
2.Connect anode to HDK board A3, and cathode to GND
|
||||
|
||||
3.Run the main function.
|
||||
|
||||
4.Will see result like below
|
||||
|
||||
AD1:00008049 = 1644 mv, AD2:00002a75 = 17 mv, AD3:00002a94 = 20 mv
|
||||
|
||||
|
||||
NOTE:
|
||||
1. For 8195AM EVB, A0 and A1 are hardware connected. A2 is also available.
|
||||
For 8711AM EVB, A0 and A1 are not available. Only A2 is avaliable.
|
||||
2. ADC need calibration to get correct voltage value by modifing OFFSET and GAIN_DIV.
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "analogin_api.h"
|
||||
#include <sys_api.h>
|
||||
|
||||
#define ADC_CALIBRATION 0
|
||||
#define MBED_ADC_EXAMPLE_PIN_1 AD_1 // no pin out
|
||||
#define MBED_ADC_EXAMPLE_PIN_2 AD_2 // HDK, A1
|
||||
#define MBED_ADC_EXAMPLE_PIN_3 AD_3 // HDK, A2
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
analogin_t adc0;
|
||||
analogin_t adc1;
|
||||
analogin_t adc2;
|
||||
#else
|
||||
volatile analogin_t adc0;
|
||||
volatile analogin_t adc1;
|
||||
volatile analogin_t adc2;
|
||||
#endif
|
||||
|
||||
void adc_delay(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<1600000;i++)
|
||||
asm(" nop");
|
||||
}
|
||||
|
||||
uint16_t adcdat0 = 0;
|
||||
uint16_t adcdat1 = 0;
|
||||
uint16_t adcdat2 = 0;
|
||||
|
||||
int32_t v_mv0;
|
||||
int32_t v_mv1;
|
||||
int32_t v_mv2;
|
||||
|
||||
/*
|
||||
* OFFSET: value of measuring at 0.000v, value(0.000v)
|
||||
* GAIN_DIV: value(1.000v)-value(0.000v) or value(2.000v)-value(1.000v) or value(3.000v)-value(2.000v)
|
||||
*
|
||||
* MSB 12bit of value is valid, need to truncate LSB 4bit (0xABCD -> 0xABC). OFFSET and GAIN_DIV are truncated values.
|
||||
*/
|
||||
#define OFFSET 0x298
|
||||
#define GAIN_DIV 0x34C
|
||||
#define AD2MV(ad,offset,gain) (((ad/16)-offset)*1000/gain)
|
||||
|
||||
VOID
|
||||
main (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
uint16_t offset, gain;
|
||||
analogin_init(&adc0, MBED_ADC_EXAMPLE_PIN_1); // no pinout on HDK board
|
||||
analogin_init(&adc1, MBED_ADC_EXAMPLE_PIN_2);
|
||||
analogin_init(&adc2, MBED_ADC_EXAMPLE_PIN_3);
|
||||
#if ADC_CALIBRATION
|
||||
sys_adc_calibration(0, &offset, &gain);
|
||||
printf("ADC:offset = 0x%x, gain = 0x%x\n", offset, gain);
|
||||
if((offset==0xFFFF) || (gain==0xFFFF))
|
||||
#endif
|
||||
{
|
||||
offset = OFFSET;
|
||||
gain = GAIN_DIV;
|
||||
printf("ADC:offset = 0x%x, gain = 0x%x\n", offset, gain);
|
||||
}
|
||||
for (;;){
|
||||
adcdat0 = analogin_read_u16(&adc0);
|
||||
adcdat1 = analogin_read_u16(&adc1);
|
||||
adcdat2 = analogin_read_u16(&adc2);
|
||||
|
||||
v_mv0 = AD2MV(adcdat0, offset, gain);
|
||||
v_mv1 = AD2MV(adcdat1, offset, gain);
|
||||
v_mv2 = AD2MV(adcdat2, offset, gain);
|
||||
|
||||
printf("AD0:%x = %d mv, AD1:%x = %d mv, AD2:%x = %d mv\n", adcdat0, v_mv0, adcdat1, v_mv1, adcdat2, v_mv2);
|
||||
adc_delay();
|
||||
}
|
||||
analogin_deinit(&adc0);
|
||||
analogin_deinit(&adc1);
|
||||
analogin_deinit(&adc2);
|
||||
}
|
||||
7
project/realtek_ameba1_va0_example/example_sources/crypto/readme.txt
Executable file
7
project/realtek_ameba1_va0_example/example_sources/crypto/readme.txt
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use CRYPTO function, it is based on cutomer requirement modified.
|
||||
|
||||
use Arduino board to test, and it will show at console
|
||||
|
||||
|
||||
408
project/realtek_ameba1_va0_example/example_sources/crypto/src/main.c
Executable file
408
project/realtek_ameba1_va0_example/example_sources/crypto/src/main.c
Executable file
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "hal_crypto.h"
|
||||
#include "main.h"
|
||||
#include "diag.h"
|
||||
#include <polarssl/aes.h>
|
||||
|
||||
#define STACKSIZE 2048
|
||||
|
||||
//static const u8 plaintext[] = "The quick brown fox jumps over the lazy dog";
|
||||
//static const u8 md5_digest[] = "\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
|
||||
// "\x6b\xd8\x1d\x35\x42\xa4\x19\xd6";
|
||||
//static const u8 md5_key[] = "key";
|
||||
|
||||
static const char plaintext[] = "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890";
|
||||
static const char md5_digest[] = { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
||||
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A };
|
||||
static const u8 md5_key[] = "key";
|
||||
|
||||
static unsigned char md5_test_buf[16][128] =
|
||||
{
|
||||
{ "" },
|
||||
{ "a" },
|
||||
{ "abc" },
|
||||
{ "message digest" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||
{ "The quick brown fox jumps over the lazy dog" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890" },
|
||||
{ "" },
|
||||
{ "a" },
|
||||
{ "abc" },
|
||||
{ "message digest" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz" },
|
||||
{ "The quick brown fox jumps over the lazy dog" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012" \
|
||||
"345678901234567890" }
|
||||
};
|
||||
|
||||
static const int md5_test_buflen[16] =
|
||||
{
|
||||
0, 1, 3, 14, 26, 43, 62, 80, 0, 1, 3, 14, 26, 43, 62, 80
|
||||
};
|
||||
|
||||
static const unsigned char md5_test_sum[16][16] =
|
||||
{
|
||||
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
||||
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
|
||||
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
|
||||
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
|
||||
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
|
||||
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
|
||||
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
|
||||
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
|
||||
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
|
||||
{"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
|
||||
"\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"},
|
||||
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
|
||||
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
|
||||
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
||||
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A },
|
||||
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
||||
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
|
||||
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
|
||||
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
|
||||
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
|
||||
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
|
||||
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
|
||||
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
|
||||
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
|
||||
{"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
|
||||
"\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"},
|
||||
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
|
||||
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
|
||||
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
|
||||
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A },
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
u8 digest[64];
|
||||
u8 cipher_result[2048];
|
||||
u8 test_result[1024];
|
||||
|
||||
serial_t sobj;
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* This test_md5 function is used to test hardware md5 functoinality
|
||||
*/
|
||||
void test_md5(void)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
u8 md5sum[16];
|
||||
|
||||
DiagPrintf("MD5 test\r\n");
|
||||
|
||||
ret = rtl_crypto_md5(plaintext, strlen(plaintext), (unsigned char *)&digest); // the length of MD5's digest is 16 bytes.
|
||||
|
||||
if ( rtl_memcmpb(digest, md5_digest, 16) == 0 ) {
|
||||
DiagPrintf("MD5 test result is correct, ret=%d\r\n", ret);
|
||||
} else {
|
||||
DiagPrintf("MD5 test result is WRONG!!, ret=%d\r\n", ret);
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
DiagPrintf( " MD5 test #%d: ", i + 1 );
|
||||
ret = rtl_crypto_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); // the length of MD5's digest is 16 bytes.
|
||||
DiagPrintf(" MD5 ret=%d\n", ret);
|
||||
if( rtl_memcmpb( md5sum, md5_test_sum[i], 16 ) != 0 )
|
||||
{
|
||||
DiagPrintf( "failed\n" );
|
||||
memset(md5sum,0,16);
|
||||
}
|
||||
else{
|
||||
DiagPrintf( "passed\n" );
|
||||
memset(md5sum,0,16);}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// vector : AES CBC 128 bit :
|
||||
// http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
//
|
||||
|
||||
//#ifdef __ICCARM__
|
||||
//#pragma data_alignment = 4
|
||||
//#elif defined (__GNUC__)
|
||||
//__attribute__ ((aligned (4)))
|
||||
//#endif
|
||||
static const unsigned char aes_test_key[16] =
|
||||
{
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
|
||||
} ;
|
||||
|
||||
|
||||
//#ifdef __ICCARM__
|
||||
//#pragma data_alignment = 4
|
||||
//#elif defined (__GNUC__)
|
||||
//__attribute__ ((aligned (4)))
|
||||
//#endif
|
||||
static const unsigned char aes_test_iv_1[16] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
|
||||
static const unsigned char aes_test_buf[16] =
|
||||
{
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
};
|
||||
static const unsigned char aes_test_ecb_buf[160] =
|
||||
{
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const unsigned char aes_test_res_128[16] =
|
||||
{
|
||||
0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
|
||||
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d
|
||||
};
|
||||
|
||||
static const unsigned char aes_test_ecb_res_128[160] =
|
||||
{
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* THis test_aes_cbc function is use to directly test hardware aes cbc crypto functionality
|
||||
*
|
||||
*/
|
||||
int test_aes_cbc(void)
|
||||
{
|
||||
const u8 *key, *pIv;
|
||||
u32 keylen= 0;
|
||||
u32 ivlen = 0;
|
||||
u8 *message;
|
||||
u32 msglen;
|
||||
u8 *pResult;
|
||||
|
||||
int ret;
|
||||
|
||||
DiagPrintf("AES CBC test\r\n");
|
||||
|
||||
key = aes_test_key;
|
||||
keylen = 16;
|
||||
pIv = aes_test_iv_1;
|
||||
ivlen = 16;
|
||||
|
||||
pResult = cipher_result;
|
||||
|
||||
message = (unsigned char *)aes_test_buf;
|
||||
msglen = sizeof(aes_test_buf);
|
||||
ret = rtl_crypto_aes_cbc_init(key,keylen);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES CBC init failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtl_crypto_aes_cbc_encrypt(message, msglen, pIv, ivlen, pResult);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES CBC encrypt failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
if ( rtl_memcmpb(aes_test_res_128, pResult, msglen) == 0 ) {
|
||||
DiagPrintf("AES CBC encrypt result success\r\n");
|
||||
} else {
|
||||
DiagPrintf("AES CBC encrypt result failed\r\n");
|
||||
}
|
||||
|
||||
message = pResult;
|
||||
|
||||
ret = rtl_crypto_aes_cbc_decrypt(message, msglen, pIv, ivlen, pResult);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES CBC decrypt failed, ret=%d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( rtl_memcmpb(aes_test_buf, pResult, msglen) == 0 ) {
|
||||
DiagPrintf("AES CBC decrypt result success\r\n");
|
||||
} else {
|
||||
DiagPrintf("AES CBC decrypt result failed\r\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* THis test_aes_ecb function is use to directly test hardware ecb cbc crypto functionality
|
||||
*
|
||||
* The input parameter for ecb need to confirm iv is null and ivlen is 0
|
||||
*/
|
||||
int test_aes_ecb(void)
|
||||
{
|
||||
|
||||
const u8 *key, *pIv;
|
||||
u32 keylen= 0;
|
||||
u32 ivlen = 0;
|
||||
u8 *message;
|
||||
u32 msglen;
|
||||
u8 *pResult;
|
||||
|
||||
int ret;
|
||||
|
||||
DiagPrintf("AES ECB test\r\n");
|
||||
|
||||
key = aes_test_key;
|
||||
keylen = 16;
|
||||
pIv = NULL;
|
||||
ivlen = 0;
|
||||
|
||||
pResult = cipher_result;
|
||||
message = (unsigned char *)aes_test_ecb_buf;
|
||||
msglen = sizeof(aes_test_buf);
|
||||
//for(int i=0;i<msglen;i++)
|
||||
//printf("\r\n first message[%d] = %p,",i,message[i]);
|
||||
ret = rtl_crypto_aes_ecb_init(key,keylen);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES ECB init failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtl_crypto_aes_ecb_encrypt(message, msglen, pIv, ivlen, pResult);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES ECB encrypt failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( rtl_memcmpb(aes_test_ecb_res_128, pResult, msglen) == 0 )
|
||||
{
|
||||
DiagPrintf("AES ECB encrypt result success\r\n");
|
||||
}
|
||||
else {
|
||||
DiagPrintf("AES ECB encrypt result failed\r\n");
|
||||
}
|
||||
|
||||
message = pResult;
|
||||
//for(int i=0;i<msglen;i++)
|
||||
//printf("\r\n second message[%d] = %p,",i,message[i]);
|
||||
ret = rtl_crypto_aes_ecb_decrypt(message, msglen, pIv, ivlen, pResult);
|
||||
if ( ret != 0 ) {
|
||||
DiagPrintf("AES ECB decrypt failed, ret=%d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( rtl_memcmpb(aes_test_ecb_buf, pResult, msglen) == 0 )
|
||||
{
|
||||
DiagPrintf("AES ECB decrypt result success\r\n");
|
||||
}
|
||||
else {
|
||||
DiagPrintf("AES ECB decrypt result failed\r\n");
|
||||
}
|
||||
|
||||
//for(int i=0;i<msglen;i++)
|
||||
//printf("\r\n last message[%d] = %p,",i,message[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// sample text
|
||||
char rc;
|
||||
//
|
||||
int ret;
|
||||
int loop=0;
|
||||
u32 keylen= 0;
|
||||
u32 ivlen = 0;
|
||||
u8 *pResult;
|
||||
u8 *message;
|
||||
u32 *ResultLen;
|
||||
u32 msglen = 0;
|
||||
const u8 *key, *pIv;
|
||||
key = aes_test_key;
|
||||
keylen = 16;
|
||||
pIv = aes_test_iv_1;
|
||||
ivlen = 16;
|
||||
//
|
||||
message = (unsigned char *)aes_test_buf;
|
||||
msglen = sizeof(aes_test_buf);
|
||||
|
||||
|
||||
DiagPrintf("CRYPTO API Demo...\r\n");
|
||||
|
||||
if ( rtl_cryptoEngine_init() != 0 ) {
|
||||
DiagPrintf("crypto engine init failed\r\n");
|
||||
}
|
||||
else
|
||||
printf("init success\n");
|
||||
|
||||
|
||||
pResult = test_result;
|
||||
test_md5();
|
||||
test_aes_cbc();
|
||||
test_aes_ecb();
|
||||
//aes_test(); //added api combined aes_cbc setkey and cryption into one function
|
||||
|
||||
}
|
||||
|
||||
10
project/realtek_ameba1_va0_example/example_sources/efuse_user/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/efuse_user/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to read/write efuse in user blocks.
|
||||
|
||||
There are three blocks, each block has 32 bytes.
|
||||
|
||||
Requirement Components:
|
||||
None
|
||||
|
||||
|
||||
137
project/realtek_ameba1_va0_example/example_sources/efuse_user/src/main.c
Executable file
137
project/realtek_ameba1_va0_example/example_sources/efuse_user/src/main.c
Executable file
|
|
@ -0,0 +1,137 @@
|
|||
#include "diag.h"
|
||||
#include "hal_efuse.h"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// There are three blocks, each block has 32 bytes.
|
||||
u8 CodeWordNum; // 0~3, 0: 1~8 bytes, 1: 9~16 bytes, 2: 17~24 bytes, 3: 25~32 bytes
|
||||
u8 WordEnable; // 0x0~0xF, 4bits, 1 bit is for 2 bytes, Max: 8 bytes.
|
||||
// bit0: 1,2 byte , bit1: 3,4 byte , bit2: 5,6 byte , bit3: 7,8 byte
|
||||
u8 content[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
u8 i;
|
||||
// Block 1
|
||||
u8 text1_0[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
|
||||
u8 text1_1[8] = {0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
|
||||
u8 text1_2[8] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17};
|
||||
u8 text1_3[8] = {0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
|
||||
// Block 2
|
||||
u8 text2_0[8] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};
|
||||
u8 text2_1[8] = {0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F};
|
||||
u8 text2_2[8] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37};
|
||||
u8 text2_3[8] = {0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F};
|
||||
// Block 3
|
||||
u8 text3_0[8] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
|
||||
u8 text3_1[8] = {0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F};
|
||||
u8 text3_2[8] = {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57};
|
||||
u8 text3_3[8] = {0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F};
|
||||
|
||||
u8 bWriteBlock1 = 0;
|
||||
u8 bWriteBlock2 = 0;
|
||||
u8 bWriteBlock3 = 0;
|
||||
|
||||
DBG_8195A("\nefuse user block: Test Start\n");
|
||||
//------------------------------------------------//
|
||||
// efuse user block 1 //
|
||||
//------------------------------------------------//
|
||||
// write efuse user block 1
|
||||
if(bWriteBlock1){
|
||||
// write 1~8 bytes in block 1
|
||||
CodeWordNum = 0;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_0) == _SUCCESS);
|
||||
DBG_8195A("write 1~8 bytes of block 1 success.\n");
|
||||
// write 9~16 bytes in block 1
|
||||
CodeWordNum = 1;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_1) == _SUCCESS);
|
||||
DBG_8195A("write 9~16 bytes of block 1 success.\n");
|
||||
// write 17~24 bytes in block 1
|
||||
CodeWordNum = 2;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_2) == _SUCCESS);
|
||||
DBG_8195A("write 17~24 bytes of block 1 success.\n");
|
||||
// write 25~32 bytes in block 1
|
||||
CodeWordNum = 3;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_3) == _SUCCESS);
|
||||
DBG_8195A("write 25~32 bytes of block 1 success.\n");
|
||||
}
|
||||
// read efuse user block 1, read 32 bytes once.
|
||||
_memset(content, 0, 32);
|
||||
ReadEfuseContant1(content);
|
||||
DBG_8195A("efuse user block 1 :\n");
|
||||
for(i=0; i<32; i++){
|
||||
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
// efuse user block 2 //
|
||||
//------------------------------------------------//
|
||||
// write efuse user block 2
|
||||
if(bWriteBlock2){
|
||||
// write 1~8 bytes in block 2
|
||||
CodeWordNum = 0;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_0) == _SUCCESS);
|
||||
DBG_8195A("write 1~8 bytes of block 2 success.\n");
|
||||
// write 9~16 bytes in block 2
|
||||
CodeWordNum = 1;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_1) == _SUCCESS);
|
||||
DBG_8195A("write 9~16 bytes of block 2 success.\n");
|
||||
// write 17~24 bytes in block 2
|
||||
CodeWordNum = 2;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_2) == _SUCCESS);
|
||||
DBG_8195A("write 17~24 bytes of block 2 success.\n");
|
||||
// write 25~32 bytes in block 2
|
||||
CodeWordNum = 3;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_3) == _SUCCESS);
|
||||
DBG_8195A("write 25~32 bytes of block 2 success.\n");
|
||||
}
|
||||
// read efuse user block 2, read 32 bytes once.
|
||||
_memset(content, 0, 32);
|
||||
ReadEfuseContant2(content);
|
||||
DBG_8195A("efuse user block 2 :\n");
|
||||
for(i=0; i<32; i++){
|
||||
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
// efuse user block 3 //
|
||||
//------------------------------------------------//
|
||||
// write efuse user block 3
|
||||
if(bWriteBlock3){
|
||||
// write 1~8 bytes in block 3
|
||||
CodeWordNum = 0;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_0) == _SUCCESS);
|
||||
DBG_8195A("write 1~8 bytes of block 3 success.\n");
|
||||
// write 9~16 bytes in block 3
|
||||
CodeWordNum = 1;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_1) == _SUCCESS);
|
||||
DBG_8195A("write 9~16 bytes of block 3 success.\n");
|
||||
// write 17~24 bytes in block 3
|
||||
CodeWordNum = 2;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_2) == _SUCCESS);
|
||||
DBG_8195A("write 17~24 bytes of block 3 success.\n");
|
||||
// write 25~32 bytes in block 3
|
||||
CodeWordNum = 3;
|
||||
WordEnable = 0xF; // max: 8 bytes
|
||||
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_3) == _SUCCESS);
|
||||
DBG_8195A("write 25~32 bytes of block 3 success.\n");
|
||||
}
|
||||
// read efuse user block 3, read 32 bytes once.
|
||||
_memset(content, 0, 32);
|
||||
ReadEfuseContant3(content);
|
||||
DBG_8195A("efuse user block 3 :\n");
|
||||
for(i=0; i<32; i++){
|
||||
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
|
||||
}
|
||||
|
||||
DBG_8195A("efuse user block: Test Done\n");
|
||||
for(;;);
|
||||
}
|
||||
8
project/realtek_ameba1_va0_example/example_sources/flash/readme.txt
Executable file
8
project/realtek_ameba1_va0_example/example_sources/flash/readme.txt
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
Example Description
|
||||
|
||||
This example read a specific flash offset, modify it and re-read again.
|
||||
|
||||
Requirement Components:
|
||||
None
|
||||
|
||||
|
||||
95
project/realtek_ameba1_va0_example/example_sources/flash/src/main.c
Executable file
95
project/realtek_ameba1_va0_example/example_sources/flash/src/main.c
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "objects.h"
|
||||
#include "flash_api.h"
|
||||
|
||||
// Decide starting flash address for storing application data
|
||||
// User should pick address carefully to avoid corrupting image section
|
||||
|
||||
#define FLASH_APP_BASE 0xFF000
|
||||
|
||||
void main(void)
|
||||
{
|
||||
flash_t flash;
|
||||
uint32_t address = FLASH_APP_BASE;
|
||||
|
||||
#if 1
|
||||
uint32_t val32_to_write = 0x13572468;
|
||||
uint32_t val32_to_read;
|
||||
int loop = 0;
|
||||
int result = 0;
|
||||
for(loop = 0; loop < 10; loop++)
|
||||
{
|
||||
flash_read_word(&flash, address, &val32_to_read);
|
||||
DBG_8195A("Read Data 0x%x\n", val32_to_read);
|
||||
flash_erase_sector(&flash, address);
|
||||
flash_write_word(&flash, address, val32_to_write);
|
||||
flash_read_word(&flash, address, &val32_to_read);
|
||||
|
||||
DBG_8195A("Read Data 0x%x\n", val32_to_read);
|
||||
|
||||
// verify result
|
||||
result = (val32_to_write == val32_to_read) ? 1 : 0;
|
||||
//printf("\r\nResult is %s\r\n", (result) ? "success" : "fail");
|
||||
DBG_8195A("\r\nResult is %s\r\n", (result) ? "success" : "fail");
|
||||
result = 0;
|
||||
}
|
||||
#else
|
||||
int VERIFY_SIZE = 256;
|
||||
int SECTOR_SIZE = 16;
|
||||
|
||||
uint8_t writedata[VERIFY_SIZE];
|
||||
uint8_t readdata[VERIFY_SIZE];
|
||||
uint8_t verifydata = 0;
|
||||
int loop = 0;
|
||||
int index = 0;
|
||||
int sectorindex = 0;
|
||||
int result = 0;
|
||||
int resultsector = 0;
|
||||
int testloop = 0;
|
||||
for(testloop = 0; testloop < 1; testloop++){
|
||||
address = FLASH_APP_BASE;
|
||||
for(sectorindex = 0; sectorindex < 4080; sectorindex++){
|
||||
result = 0;
|
||||
//address += SECTOR_SIZE;
|
||||
flash_erase_sector(&flash, address);
|
||||
//DBG_8195A("Address = %x \n", address);
|
||||
for(loop = 0; loop < SECTOR_SIZE; loop++){
|
||||
for(index = 0; index < VERIFY_SIZE; index++)
|
||||
{
|
||||
writedata[index] = verifydata + index;
|
||||
}
|
||||
flash_stream_write(&flash, address, VERIFY_SIZE, &writedata);
|
||||
flash_stream_read(&flash, address, VERIFY_SIZE, &readdata);
|
||||
|
||||
for(index = 0; index < VERIFY_SIZE; index++)
|
||||
{
|
||||
//DBG_8195A("Address = %x, Writedata = %x, Readdata = %x \n",address,writedata[index],readdata[index]);
|
||||
if(readdata[index] != writedata[index]){
|
||||
DBG_8195A("Error: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n",testloop,address,writedata[index],readdata[index]);
|
||||
}
|
||||
else{
|
||||
result++;
|
||||
//DBG_8195A(ANSI_COLOR_BLUE"Correct: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n"ANSI_COLOR_RESET,testloop,address,writedata[index],readdata[index]);
|
||||
}
|
||||
}
|
||||
address += VERIFY_SIZE;
|
||||
}
|
||||
if(result == VERIFY_SIZE * SECTOR_SIZE){
|
||||
//DBG_8195A("Sector %d Success \n", sectorindex);
|
||||
resultsector++;
|
||||
}
|
||||
}
|
||||
if(resultsector == 4079){
|
||||
DBG_8195A("Test Loop %d Success \n", testloop);
|
||||
}
|
||||
resultsector = 0;
|
||||
verifydata++;
|
||||
}
|
||||
//DBG_8195A("%d Sector Success \n", resultsector);
|
||||
DBG_8195A("Test Done");
|
||||
|
||||
#endif
|
||||
for(;;);
|
||||
}
|
||||
158
project/realtek_ameba1_va0_example/example_sources/gdma/src/main.c
Executable file
158
project/realtek_ameba1_va0_example/example_sources/gdma/src/main.c
Executable file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "dma_api.h"
|
||||
|
||||
#if 1
|
||||
//Multi-Block Example Demo
|
||||
#define DMA_CPY_LEN 176
|
||||
#define DMA_BLOCK_LENGTH 22
|
||||
#define DMA_SRC_OFFSET 0
|
||||
#define DMA_DST_OFFSET 0
|
||||
#define BLOCK_NUM 8
|
||||
|
||||
gdma_t gdma;
|
||||
uint8_t TestBuf1[DMA_CPY_LEN];
|
||||
uint8_t TestBuf2[DMA_CPY_LEN];
|
||||
volatile uint8_t dma_done;
|
||||
|
||||
struct BlockInfo{
|
||||
u32 SrcAddr;
|
||||
u32 DstAddr;
|
||||
u32 BlockLength;
|
||||
u32 SrcOffset;
|
||||
u32 DstOffset;
|
||||
};
|
||||
|
||||
void dma_done_handler(uint32_t id) {
|
||||
DiagPrintf("DMA Copy Done!!\r\n");
|
||||
dma_done = 1;
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
int i = 0,err = 0;
|
||||
struct BlockInfo block_info[BLOCK_NUM];
|
||||
//Set how many blocks we want to transfer (16 at most)
|
||||
gdma.gdma_obj.BlockNum = BLOCK_NUM;
|
||||
//Initialize DMA multi-block mode setting
|
||||
dma_memcpy_aggr_init(&gdma, dma_done_handler, (uint32_t) &gdma);
|
||||
|
||||
_memset(TestBuf1, 0,DMA_CPY_LEN);
|
||||
|
||||
for(i = 0; i < DMA_CPY_LEN; i++){
|
||||
TestBuf1[i] = DMA_CPY_LEN - 1 - i;
|
||||
}
|
||||
|
||||
_memset(TestBuf2, 0,DMA_CPY_LEN);
|
||||
dma_done = 0;
|
||||
|
||||
for(i = 0; i < BLOCK_NUM; i++){
|
||||
//User can decide the relation between SrcOffset/DstOffset,SrcAddr/DstAddr and Block length
|
||||
// For example :
|
||||
//block_info[i].SrcOffset = 0;
|
||||
//block_info[i].DstOffset = 4;
|
||||
//block_info[i].SrcAddr = &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC
|
||||
//block_info[i].DstAddr = &TestBuf2[0] + (DMA_BLOCK_LENGTH + block_info[i].DstOffset )*i;//Dest
|
||||
//block_info[i].BlockLength = DMA_BLOCK_LENGTH;
|
||||
|
||||
block_info[i].SrcOffset = 0;
|
||||
block_info[i].DstOffset = 0;
|
||||
block_info[i].SrcAddr = (uint32_t) &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC
|
||||
block_info[i].DstAddr = (uint32_t) &TestBuf2[ i * DMA_BLOCK_LENGTH] ;//Dest
|
||||
block_info[i].BlockLength = DMA_BLOCK_LENGTH;
|
||||
//DiagPrintf("block_info[%d].SrcAddr = %x\r\n",i, block_info[i].SrcAddr);
|
||||
//DiagPrintf("block_info[%d].DstAddr = %x\r\n",i, block_info[i].DstAddr);
|
||||
//DiagPrintf("block_info[%d].BlockLength = %x\r\n",i, block_info[i].BlockLength);
|
||||
//DiagPrintf("block_info[%d].SrcOffset = %x\r\n",i, block_info[i].SrcOffset);
|
||||
//DiagPrintf("block_info[%d].DstOffset = %x\r\n",i, block_info[i].DstOffset);
|
||||
}
|
||||
|
||||
|
||||
dma_memcpy_aggr(&gdma, (PHAL_GDMA_BLOCK) &block_info);
|
||||
|
||||
while (dma_done == 0);
|
||||
|
||||
err = 0;
|
||||
for (i=0;i<DMA_CPY_LEN;i++) {
|
||||
//DiagPrintf("dma_done = %x\r\n", dma_done);
|
||||
//DiagPrintf("TestBuf2[%d] = %x\r\n",i, TestBuf2[i]);
|
||||
if (TestBuf2[i+DMA_DST_OFFSET] != TestBuf1[i+DMA_SRC_OFFSET]) {
|
||||
DiagPrintf("DMA Copy Memory Compare Err, %d %x %x\r\n", i, TestBuf1[i+DMA_SRC_OFFSET], TestBuf2[i+DMA_DST_OFFSET]);
|
||||
DiagPrintf("DMA done = %x\r\n", dma_done);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
DiagPrintf("DMA Copy Memory Compare OK!! %x\r\n", TestBuf2[DMA_DST_OFFSET+DMA_CPY_LEN - 1]);
|
||||
}
|
||||
|
||||
HalGdmaMemCpyDeInit(&(gdma.gdma_obj));
|
||||
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
//Single-Block Example Demo
|
||||
|
||||
#define DMA_CPY_LEN 256
|
||||
#define DMA_SRC_OFFSET 0
|
||||
#define DMA_DST_OFFSET 0
|
||||
|
||||
gdma_t gdma;
|
||||
uint8_t TestBuf1[512];
|
||||
uint8_t TestBuf2[512];
|
||||
volatile uint8_t dma_done;
|
||||
|
||||
|
||||
void dma_done_handler(uint32_t id) {
|
||||
DiagPrintf("DMA Copy Done!!\r\n");
|
||||
dma_done = 1;
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
int i;
|
||||
int err;
|
||||
|
||||
dma_memcpy_init(&gdma, dma_done_handler, (uint32_t)&gdma);
|
||||
for (i=0;i< 512;i++) {
|
||||
TestBuf1[i] = i;
|
||||
}
|
||||
_memset(TestBuf2, 0xff, 512);
|
||||
|
||||
dma_done = 0;
|
||||
dma_memcpy(&gdma, TestBuf2+DMA_DST_OFFSET, TestBuf1+DMA_SRC_OFFSET, DMA_CPY_LEN);
|
||||
|
||||
while (dma_done == 0);
|
||||
|
||||
err = 0;
|
||||
for (i=0;i<DMA_CPY_LEN;i++) {
|
||||
if (TestBuf2[i+DMA_DST_OFFSET] != TestBuf1[i+DMA_SRC_OFFSET]) {
|
||||
DiagPrintf("DMA Copy Memory Compare Err, %d %x %x\r\n", i, TestBuf1[i+DMA_SRC_OFFSET], TestBuf2[i+DMA_DST_OFFSET]);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
DiagPrintf("DMA Copy Memory Compare OK!! %x\r\n", TestBuf2[DMA_DST_OFFSET+DMA_CPY_LEN]);
|
||||
}
|
||||
HalGdmaMemCpyDeInit(&(gdma.gdma_obj));
|
||||
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
14
project/realtek_ameba1_va0_example/example_sources/gpio/readme.txt
Executable file
14
project/realtek_ameba1_va0_example/example_sources/gpio/readme.txt
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use GPIO read/write by mbed api.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
- PC_4 as input with internal pull-high, connect a push button to this pin and ground.
|
||||
- PC_5 as output, connect a LED to this pin and ground.
|
||||
|
||||
In this example, the LED is on when the push button is pressed.
|
||||
|
||||
49
project/realtek_ameba1_va0_example/example_sources/gpio/src/main.c
Executable file
49
project/realtek_ameba1_va0_example/example_sources/gpio/src/main.c
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN PC_5
|
||||
#define GPIO_PUSHBT_PIN PC_4
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
//int main_app(IN u16 argc, IN u8 *argv[])
|
||||
void main(void)
|
||||
{
|
||||
gpio_t gpio_led;
|
||||
gpio_t gpio_btn;
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
// Initial Push Button pin
|
||||
gpio_init(&gpio_btn, GPIO_PUSHBT_PIN);
|
||||
gpio_dir(&gpio_btn, PIN_INPUT); // Direction: Input
|
||||
gpio_mode(&gpio_btn, PullUp); // Pull-High
|
||||
|
||||
while(1){
|
||||
if (gpio_read(&gpio_btn)) {
|
||||
// turn off LED
|
||||
gpio_write(&gpio_led, 0);
|
||||
}
|
||||
else {
|
||||
// turn on LED
|
||||
gpio_write(&gpio_led, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
project/realtek_ameba1_va0_example/example_sources/gpio_irq/readme.txt
Executable file
13
project/realtek_ameba1_va0_example/example_sources/gpio_irq/readme.txt
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use GPIO read/write by mbed api.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
- PC_4 as input with internal pull-high, connect a push button to this pin and ground.
|
||||
- PC_5 as output, connect a LED to this pin and ground.
|
||||
|
||||
In this example, push the button to trigger interrupt to turn on/off the LED.
|
||||
59
project/realtek_ameba1_va0_example/example_sources/gpio_irq/src/main.c
Executable file
59
project/realtek_ameba1_va0_example/example_sources/gpio_irq/src/main.c
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN PC_5
|
||||
#define GPIO_IRQ_PIN PC_4
|
||||
|
||||
int led_ctrl;
|
||||
gpio_t gpio_led;
|
||||
|
||||
extern u32 ConfigDebugWarn;
|
||||
|
||||
void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
gpio_t *gpio_led;
|
||||
|
||||
DBG_GPIO_WARN("%s==>\n", __FUNCTION__);
|
||||
gpio_led = (gpio_t *)id;
|
||||
|
||||
led_ctrl = !led_ctrl;
|
||||
gpio_write(gpio_led, led_ctrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
gpio_irq_t gpio_btn;
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led));
|
||||
gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_btn);
|
||||
|
||||
led_ctrl = 1;
|
||||
gpio_write(&gpio_led, led_ctrl);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
14
project/realtek_ameba1_va0_example/example_sources/gpio_jtag/readme.txt
Executable file
14
project/realtek_ameba1_va0_example/example_sources/gpio_jtag/readme.txt
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to disable JTAG module and use GPIO pin to blink led.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
PC_4 as input with internal pull-high, connect a push button to this pin and ground.
|
||||
If button is not pressed while device boot up, then jtag module is turned off.
|
||||
If button is pressed while device boot up, then we don't turn off jtag module.
|
||||
|
||||
PE_0 as output, connect a LED to this pin and ground.
|
||||
If jatg module is turned off, then we blink led.
|
||||
56
project/realtek_ameba1_va0_example/example_sources/gpio_jtag/src/main.c
Executable file
56
project/realtek_ameba1_va0_example/example_sources/gpio_jtag/src/main.c
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "sys_api.h" // for sys_jtag_off()
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_JTAG_ENABLE_PIN PC_4
|
||||
#define GPIO_LED_PIN PE_0
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
gpio_t gpio_jtag_enable;
|
||||
gpio_t gpio_led;
|
||||
|
||||
gpio_init(&gpio_jtag_enable, GPIO_JTAG_ENABLE_PIN);
|
||||
gpio_dir(&gpio_jtag_enable, PIN_INPUT);
|
||||
gpio_mode(&gpio_jtag_enable, PullUp);
|
||||
|
||||
if (gpio_read(&gpio_jtag_enable) == 0)
|
||||
{
|
||||
// JTAG enable pin is disabled
|
||||
sys_jtag_off();
|
||||
printf("jtag off\r\n");
|
||||
|
||||
// Now you can use jtag pin for other gpio usage
|
||||
// ex. use PE_0 to blink led
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
while(1)
|
||||
{
|
||||
gpio_write(&gpio_led, 1);
|
||||
for (i=0; i<10000000; i++) asm(" nop"); // simple delay
|
||||
gpio_write(&gpio_led, 0);
|
||||
for (i=0; i<10000000; i++) asm(" nop"); // simple delay
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// JTAG enable pin is enabled
|
||||
printf("jtag on\r\n");
|
||||
}
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
21
project/realtek_ameba1_va0_example/example_sources/gpio_level_irq/readme.txt
Executable file
21
project/realtek_ameba1_va0_example/example_sources/gpio_level_irq/readme.txt
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to implement high/low level trigger on 1 gpio pin.
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
Connect PC_4 and PC_5
|
||||
- PC_4 as gpio input high/low level trigger.
|
||||
- PC_5 as gpio output
|
||||
|
||||
In this example, PC_5 is signal source that change level to high and low periodically.
|
||||
|
||||
PC_4 setup to listen low level events in initial.
|
||||
When PC_4 catch low level events, it disable the irq to avoid receiving duplicate events.
|
||||
(NOTE: the level events will keep invoked if level keeps in same level)
|
||||
|
||||
Then PC_4 is configured to listen high level events and enable irq.
|
||||
As PC_4 catches high level events, it changes back to listen low level events.
|
||||
|
||||
Thus PC_4 can handle both high/low level events.
|
||||
|
||||
In this example, you will see log that prints high/low level event periodically.
|
||||
73
project/realtek_ameba1_va0_example/example_sources/gpio_level_irq/src/main.c
Executable file
73
project/realtek_ameba1_va0_example/example_sources/gpio_level_irq/src/main.c
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#include "gpio_irq_ex_api.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_IRQ_LEVEL_PIN PC_4
|
||||
#define GPIO_SIGNAL_SOURCE PC_5
|
||||
|
||||
gpio_irq_t gpio_level;
|
||||
int current_level = IRQ_LOW;
|
||||
|
||||
void gpio_level_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
uint32_t *level = (uint32_t *) id;
|
||||
|
||||
// Disable level irq because the irq will keep triggered when it keeps in same level.
|
||||
gpio_irq_disable(&gpio_level);
|
||||
|
||||
// make some software de-bounce here if the signal source is not stable.
|
||||
|
||||
if (*level == IRQ_LOW )
|
||||
{
|
||||
printf("low level event\r\n");
|
||||
|
||||
// Change to listen to high level event
|
||||
*level = IRQ_HIGH;
|
||||
gpio_irq_set(&gpio_level, IRQ_HIGH, 1);
|
||||
gpio_irq_enable(&gpio_level);
|
||||
}
|
||||
else if (*level == IRQ_HIGH)
|
||||
{
|
||||
printf("high level event\r\n");
|
||||
|
||||
// Change to listen to low level event
|
||||
*level = IRQ_LOW;
|
||||
gpio_irq_set(&gpio_level, IRQ_LOW, 1);
|
||||
gpio_irq_enable(&gpio_level);
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// configure level trigger handler
|
||||
gpio_irq_init(&gpio_level, GPIO_IRQ_LEVEL_PIN, gpio_level_irq_handler, (uint32_t)(¤t_level));
|
||||
gpio_irq_set(&gpio_level, IRQ_LOW, 1);
|
||||
gpio_irq_enable(&gpio_level);
|
||||
|
||||
// configure gpio as signal source for high/low level trigger
|
||||
gpio_t gpio_src;
|
||||
gpio_init(&gpio_src, GPIO_SIGNAL_SOURCE);
|
||||
gpio_dir(&gpio_src, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_src, PullNone);
|
||||
|
||||
while(1) {
|
||||
gpio_write(&gpio_src, 1);
|
||||
for (i=0; i<20000000; i++) asm("nop");
|
||||
gpio_write(&gpio_src, 0);
|
||||
for (i=0; i<20000000; i++) asm("nop");
|
||||
}
|
||||
}
|
||||
|
||||
9
project/realtek_ameba1_va0_example/example_sources/gpio_port/readme.txt
Executable file
9
project/realtek_ameba1_va0_example/example_sources/gpio_port/readme.txt
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use GPIO Port read/write by mbed api.
|
||||
|
||||
Requirement Components:
|
||||
8 LEDs
|
||||
2 bords
|
||||
|
||||
|
||||
82
project/realtek_ameba1_va0_example/example_sources/gpio_port/src/main.c
Executable file
82
project/realtek_ameba1_va0_example/example_sources/gpio_port/src/main.c
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "port_api.h" // mbed
|
||||
#include "PortNames.h" // mbed
|
||||
#include "main.h"
|
||||
|
||||
#define PORT_OUTPUT_TEST 1 //1: output test, 0: input test
|
||||
|
||||
#define LED_PATTERN_NUM 12
|
||||
port_t port0;
|
||||
const uint8_t led_pattern[LED_PATTERN_NUM]={0x81, 0x42, 0x24, 0x18, 0x00, 0x88, 0x44, 0x22, 0x11, 0xff, 0x00};
|
||||
|
||||
extern void wait_ms(u32);
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#if PORT_OUTPUT_TEST
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
port_mode(&port0, PullNone);
|
||||
// Only PortA or PortB is available now
|
||||
port_init(&port0, PortA, 0xFF, PIN_OUTPUT);
|
||||
|
||||
while(1){
|
||||
for (i=0;i<LED_PATTERN_NUM;i++) {
|
||||
port_write(&port0, led_pattern[i]);
|
||||
wait_ms(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
int value_new, value_tmp, value_old;
|
||||
int stable;
|
||||
|
||||
port_mode(&port0, PullNone);
|
||||
// Only PortA or PortB is available now
|
||||
port_init(&port0, PortA, 0xFF, PIN_INPUT);
|
||||
|
||||
value_old = port_read(&port0);
|
||||
while(1){
|
||||
// De-bonse
|
||||
value_new = port_read(&port0);
|
||||
stable = 0;
|
||||
while (stable < 3){
|
||||
value_tmp = port_read(&port0);
|
||||
if (value_new != value_tmp) {
|
||||
value_new = value_tmp;
|
||||
stable = 0;
|
||||
}
|
||||
else {
|
||||
stable++;
|
||||
}
|
||||
}
|
||||
|
||||
if (value_old != value_new) {
|
||||
DBG_8195A("0x%x\r\n", value_new);
|
||||
value_old = value_new;
|
||||
}
|
||||
wait_ms(50);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
17
project/realtek_ameba1_va0_example/example_sources/gtimer/readme.txt
Executable file
17
project/realtek_ameba1_va0_example/example_sources/gtimer/readme.txt
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use general timer.
|
||||
|
||||
Requirement Components:
|
||||
2 LED
|
||||
|
||||
Connect the two LED to port PC_0 and PC_1 respectivly.
|
||||
|
||||
Behavior:
|
||||
The two LED will blink at different frequence.
|
||||
|
||||
Two timers are intialized in this example
|
||||
(1) Periodic timer
|
||||
(2) One shut timer
|
||||
|
||||
|
||||
71
project/realtek_ameba1_va0_example/example_sources/gtimer/src/main.c
Executable file
71
project/realtek_ameba1_va0_example/example_sources/gtimer/src/main.c
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "timer_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN1 PC_0
|
||||
#define GPIO_LED_PIN2 PC_1
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
//int main_app(IN u16 argc, IN u8 *argv[])
|
||||
|
||||
gtimer_t my_timer1;
|
||||
gtimer_t my_timer2;
|
||||
gpio_t gpio_led1;
|
||||
gpio_t gpio_led2;
|
||||
volatile uint32_t time2_expired=0;
|
||||
|
||||
void timer1_timeout_handler(uint32_t id)
|
||||
{
|
||||
gpio_t *gpio_led = (gpio_t *)id;
|
||||
|
||||
gpio_write(gpio_led, !gpio_read(gpio_led));
|
||||
}
|
||||
|
||||
void timer2_timeout_handler(uint32_t id)
|
||||
{
|
||||
time2_expired = 1;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led1, GPIO_LED_PIN1);
|
||||
gpio_dir(&gpio_led1, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led1, PullNone); // No pull
|
||||
|
||||
gpio_init(&gpio_led2, GPIO_LED_PIN2);
|
||||
gpio_dir(&gpio_led2, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led2, PullNone); // No pull
|
||||
|
||||
// Initial a periodical timer
|
||||
gtimer_init(&my_timer1, TIMER0);
|
||||
gtimer_start_periodical(&my_timer1, 1000000, (void*)timer1_timeout_handler, (uint32_t)&gpio_led1);
|
||||
|
||||
// Initial a one-shout timer and re-trigger it in while loop
|
||||
gtimer_init(&my_timer2, TIMER1);
|
||||
time2_expired = 0;
|
||||
gtimer_start_one_shout(&my_timer2, 500000, (void*)timer2_timeout_handler, NULL);
|
||||
|
||||
while(1){
|
||||
if (time2_expired) {
|
||||
gpio_write(&gpio_led2, !gpio_read(&gpio_led2));
|
||||
time2_expired = 0;
|
||||
gtimer_start_one_shout(&my_timer2, 500000, (void*)timer2_timeout_handler, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
project/realtek_ameba1_va0_example/example_sources/gtimer_rtc/readme.txt
Executable file
9
project/realtek_ameba1_va0_example/example_sources/gtimer_rtc/readme.txt
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use general timer API to implement a software RTC.
|
||||
|
||||
|
||||
Behavior:
|
||||
This example will print the time message to the log UART every 1 sec.
|
||||
|
||||
|
||||
126
project/realtek_ameba1_va0_example/example_sources/gtimer_rtc/src/main.c
Executable file
126
project/realtek_ameba1_va0_example/example_sources/gtimer_rtc/src/main.c
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include <time.h>
|
||||
#include "timer_api.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
#define SW_RTC_TIMER_ID TIMER5
|
||||
|
||||
static gtimer_t sw_rtc;
|
||||
static volatile struct tm rtc_timeinfo;
|
||||
|
||||
const static u8 dim[14] = {
|
||||
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28 };
|
||||
|
||||
static inline bool is_leap_year(unsigned int year)
|
||||
{
|
||||
return (!(year % 4) && (year % 100)) || !(year % 400);
|
||||
}
|
||||
|
||||
|
||||
static u8 days_in_month (u8 month, u8 year)
|
||||
{
|
||||
u8 ret = dim [ month - 1 ];
|
||||
if (ret == 0)
|
||||
ret = is_leap_year (year) ? 29 : 28;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sw_rtc_tick_handler(uint32_t id)
|
||||
{
|
||||
if(++rtc_timeinfo.tm_sec > 59) { // Increment seconds, check for overflow
|
||||
rtc_timeinfo.tm_sec = 0; // Reset seconds
|
||||
if(++rtc_timeinfo.tm_min > 59) { // Increment minutes, check for overflow
|
||||
rtc_timeinfo.tm_min = 0; // Reset minutes
|
||||
if(++rtc_timeinfo.tm_hour > 23) { // Increment hours, check for overflow
|
||||
rtc_timeinfo.tm_hour = 0; // Reset hours
|
||||
++rtc_timeinfo.tm_yday; // Increment day of year
|
||||
if(++rtc_timeinfo.tm_wday > 6) // Increment day of week, check for overflow
|
||||
rtc_timeinfo.tm_wday = 0; // Reset day of week
|
||||
// Increment day of month, check for overflow
|
||||
if(++rtc_timeinfo.tm_mday >
|
||||
days_in_month(rtc_timeinfo.tm_mon, rtc_timeinfo.tm_year)) {
|
||||
rtc_timeinfo.tm_mday = 1; // Reset day of month
|
||||
if(++rtc_timeinfo.tm_mon > 11) { // Increment month, check for overflow
|
||||
rtc_timeinfo.tm_mon = 0; // Reset month
|
||||
rtc_timeinfo.tm_yday = 0; // Reset day of year
|
||||
++rtc_timeinfo.tm_year; // Increment year
|
||||
} // - year
|
||||
} // - month
|
||||
} // - day
|
||||
} // - hour
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_init(void)
|
||||
{
|
||||
// Initial a periodical timer
|
||||
gtimer_init(&sw_rtc, SW_RTC_TIMER_ID);
|
||||
|
||||
// Tick every 1 sec
|
||||
gtimer_start_periodical(&sw_rtc, 1000000, (void*)sw_rtc_tick_handler, (uint32_t)&sw_rtc);
|
||||
}
|
||||
|
||||
static void rtc_deinit(void)
|
||||
{
|
||||
gtimer_stop(&sw_rtc);
|
||||
gtimer_deinit(&sw_rtc);
|
||||
}
|
||||
|
||||
static void rtc_set_time(uint32_t year, uint8_t mon, uint8_t mday, uint8_t wday,
|
||||
uint8_t hour, uint8_t min, uint8_t sec)
|
||||
{
|
||||
int i;
|
||||
|
||||
gtimer_stop(&sw_rtc);
|
||||
rtc_timeinfo.tm_sec = sec;
|
||||
rtc_timeinfo.tm_min = min;
|
||||
rtc_timeinfo.tm_hour = hour;
|
||||
rtc_timeinfo.tm_mday = mday-1;
|
||||
rtc_timeinfo.tm_wday = wday-1;
|
||||
rtc_timeinfo.tm_yday = 0;
|
||||
for (i=0;i<(mon-1);i++) {
|
||||
rtc_timeinfo.tm_yday += days_in_month(i,year);
|
||||
}
|
||||
rtc_timeinfo.tm_yday += (mday-1);
|
||||
rtc_timeinfo.tm_mon = mon-1;
|
||||
rtc_timeinfo.tm_year = year;
|
||||
gtimer_start(&sw_rtc);
|
||||
}
|
||||
|
||||
static void rtc_read_time(struct tm *timeinfo)
|
||||
{
|
||||
_memcpy((void*)timeinfo, (void*)&rtc_timeinfo, sizeof(struct tm));
|
||||
timeinfo->tm_mon++;
|
||||
timeinfo->tm_mday++;
|
||||
timeinfo->tm_wday++;
|
||||
timeinfo->tm_yday++;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
|
||||
rtc_init();
|
||||
|
||||
// Give RTC a initial value: 2015/4/15 (Wed) 12:00:00
|
||||
rtc_set_time(2015, 4, 15, 3, 12, 0, 0);
|
||||
|
||||
while (1) {
|
||||
rtc_read_time(&timeinfo);
|
||||
DBG_8195A("%d-%d-%d[%d] %d:%d:%d\r\n", timeinfo.tm_year, timeinfo.tm_mon, timeinfo.tm_mday,
|
||||
timeinfo.tm_wday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
|
||||
wait_ms(1000);
|
||||
}
|
||||
rtc_deinit();
|
||||
}
|
||||
|
||||
13
project/realtek_ameba1_va0_example/example_sources/i2c-shtc1/readme.txt
Executable file
13
project/realtek_ameba1_va0_example/example_sources/i2c-shtc1/readme.txt
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2c by using mbed api
|
||||
|
||||
work with arduino extended board, which has SHTC1 temperature and humidity
|
||||
sensor
|
||||
|
||||
Connect
|
||||
- I2C3 SDA (PB_3) to extended board's SDA
|
||||
- I2C3 SCL (PB_2) to extended board's SCL
|
||||
|
||||
|
||||
|
||||
209
project/realtek_ameba1_va0_example/example_sources/i2c-shtc1/src/main.c
Executable file
209
project/realtek_ameba1_va0_example/example_sources/i2c-shtc1/src/main.c
Executable file
|
|
@ -0,0 +1,209 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include "osdep_api.h"
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "rtl_lib.h"
|
||||
|
||||
#define NO_ERROR 0x00
|
||||
#define ACK_ERROR 0x01
|
||||
#define CHECKSUM_ERROR 0x02
|
||||
#define NULL_ERROR 0x03
|
||||
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
|
||||
#define MBED_I2C_SLAVE_ADDR0 0x70
|
||||
#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
|
||||
|
||||
|
||||
#define MBED_I2C_BUS_CLK 100000 //hz
|
||||
#define I2C_DATA_MAX_LENGTH 16
|
||||
|
||||
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
|
||||
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
|
||||
int i2cdata_read_pos;
|
||||
|
||||
volatile i2c_t i2cmaster;
|
||||
|
||||
|
||||
// Sensor Commands
|
||||
#define READ_ID 0xEFC8 // command: read ID register
|
||||
#define SOFT_RESET 0x805D // soft resetSample Code for SHTC1
|
||||
#define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled
|
||||
#define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled
|
||||
#define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled
|
||||
#define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled
|
||||
|
||||
|
||||
static int SHTC1_GetID(uint16_t *id);
|
||||
static void SHTC1_WriteCommand(uint16_t cmd);
|
||||
static int SHTC1_Read2BytesAndCrc(uint16_t *data);
|
||||
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
|
||||
static float SHTC1_CalcTemperature(uint16_t rawValue);
|
||||
static float SHTC1_CalcHumidity(uint16_t rawValue);
|
||||
|
||||
|
||||
int SHTC1_Init(uint16_t *pID)
|
||||
{
|
||||
int error = NO_ERROR;
|
||||
|
||||
DiagPrintf("SHTC1_Init \r\n");
|
||||
|
||||
i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
|
||||
if (pID == NULL ) return NULL_ERROR;
|
||||
|
||||
|
||||
error = SHTC1_GetID(pID);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int SHTC1_GetID(uint16_t *id)
|
||||
{
|
||||
int error = NO_ERROR;
|
||||
uint8_t bytes[2];
|
||||
uint8_t checksum;
|
||||
|
||||
SHTC1_WriteCommand(READ_ID);
|
||||
|
||||
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1);
|
||||
i2cdata_read_pos = 0;
|
||||
error = SHTC1_Read2BytesAndCrc(id);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int SHTC1_Read2BytesAndCrc(uint16_t *data)
|
||||
{
|
||||
int error;
|
||||
int readed;
|
||||
uint8_t bytes[2];
|
||||
uint8_t checksum;
|
||||
|
||||
|
||||
|
||||
bytes[0] = i2cdata_read[i2cdata_read_pos++];
|
||||
bytes[1] = i2cdata_read[i2cdata_read_pos++];
|
||||
checksum = i2cdata_read[i2cdata_read_pos++];
|
||||
|
||||
error = SHTC1_CheckCrc(bytes, 2, checksum);
|
||||
*data = (bytes[0] << 8) | bytes[1];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
|
||||
{
|
||||
uint8_t bit; // bit mask
|
||||
uint8_t crc = 0xFF; // calculated checksum
|
||||
uint8_t byteCtr; // byte counter
|
||||
|
||||
// calculates 8-Bit checksum with given polynomial
|
||||
for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++)
|
||||
{
|
||||
crc ^= (data[byteCtr]);
|
||||
for(bit = 8; bit > 0; --bit)
|
||||
{
|
||||
if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
|
||||
else crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
|
||||
// verify checksum
|
||||
if(crc != checksum) return CHECKSUM_ERROR;
|
||||
else return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void SHTC1_WriteCommand(uint16_t cmd)
|
||||
{
|
||||
int writebytes;
|
||||
|
||||
i2cdata_write[0] = (uint8_t)(cmd >>8);
|
||||
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
|
||||
i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
|
||||
}
|
||||
|
||||
static float SHTC1_CalcTemperature(uint16_t rawValue)
|
||||
{
|
||||
return 175.0 * (float)rawValue / 65536.0 - 45.0;
|
||||
}
|
||||
|
||||
static float SHTC1_CalcHumidity(uint16_t rawValue)
|
||||
{
|
||||
return 100.0 * (float)rawValue / 65536.0;
|
||||
}
|
||||
|
||||
int SHTC1_GetTempAndHumi(float *temp, float *humi)
|
||||
{
|
||||
int error;
|
||||
uint16_t rawValueTemp;
|
||||
uint16_t rawValueHumi;
|
||||
|
||||
SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR);
|
||||
|
||||
//Wire1.requestFrom(I2C_ADR_SHTC1, 6);
|
||||
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1);
|
||||
i2cdata_read_pos = 0;
|
||||
error = NO_ERROR;
|
||||
error |= SHTC1_Read2BytesAndCrc(&rawValueTemp);
|
||||
error |= SHTC1_Read2BytesAndCrc(&rawValueHumi);
|
||||
|
||||
//diag_printf("raw temp=0x%x, raw humidity=0x%x, error=%d\n",
|
||||
// rawValueTemp, rawValueHumi, error);
|
||||
|
||||
if ( error == NO_ERROR ) {
|
||||
*temp = SHTC1_CalcTemperature(rawValueTemp);
|
||||
*humi = SHTC1_CalcHumidity(rawValueHumi);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gpio_t gpio_led;
|
||||
int led_status;
|
||||
int i2clocalcnt;
|
||||
int error;
|
||||
uint16_t shtc1_id;
|
||||
|
||||
float temperature = 1.123f;
|
||||
float humidity = 2.456f;
|
||||
|
||||
|
||||
DBG_8195A("sleep 10 sec. to wait for UART console\n");
|
||||
Mdelay(10000);
|
||||
|
||||
|
||||
DBG_8195A("start i2c example - SHTC1\n");
|
||||
|
||||
|
||||
error = SHTC1_Init(&shtc1_id);
|
||||
if ( error == NO_ERROR ) {
|
||||
DiagPrintf("SHTC1 init ok, id=0x%x\r\n", shtc1_id);
|
||||
} else {
|
||||
DiagPrintf("SHTC1 init FAILED! \r\n");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
||||
while(1){
|
||||
error = SHTC1_GetTempAndHumi(&temperature, &humidity);
|
||||
|
||||
rtl_printf("temp=%f, humidity=%f, error=%d\n",
|
||||
temperature, humidity, error);
|
||||
|
||||
Mdelay(1000);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
14
project/realtek_ameba1_va0_example/example_sources/i2c/readme.txt
Executable file
14
project/realtek_ameba1_va0_example/example_sources/i2c/readme.txt
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2c by using mbed api
|
||||
|
||||
1.Connect LOG-UART connector to PC
|
||||
|
||||
2.Connect
|
||||
- I2C3 SDA (PB_3) to I2C1 SDA (PC_4) pin,
|
||||
- I2C3 SCL (PB_2) to I2C1 SCL (PC_5) pin.
|
||||
|
||||
3.Run the main function.
|
||||
|
||||
4.Get the Master and Slave Data.
|
||||
|
||||
112
project/realtek_ameba1_va0_example/example_sources/i2c/src/main.c
Executable file
112
project/realtek_ameba1_va0_example/example_sources/i2c/src/main.c
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "PinNames.h"
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include <osdep_api.h>
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
#include "ex_api.h"
|
||||
|
||||
#define I2C_SINGLE_BOARD
|
||||
#ifndef I2C_SINGLE_BOARD
|
||||
#define I2C_DUAL_BOARD
|
||||
#endif
|
||||
#ifdef I2C_SINGLE_BOARD
|
||||
#define I2C_MASTER_DEVICE
|
||||
#define I2C_SLAVE_DEVICE
|
||||
#endif
|
||||
#ifdef I2C_DUAL_BOARD
|
||||
#define I2C_MASTER_DEVICE
|
||||
#ifndef I2C_MASTER_DEVICE
|
||||
#define I2C_SLAVE_DEVICE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
|
||||
#define MBED_I2C_SLV_SDA PC_4
|
||||
#define MBED_I2C_SLV_SCL PC_5
|
||||
|
||||
#define MBED_I2C_SLAVE_ADDR0 0xAA
|
||||
#define MBED_I2C_BUS_CLK 100000 //hz
|
||||
|
||||
#define I2C_DATA_LENGTH 125
|
||||
char i2cdatasrc[I2C_DATA_LENGTH];
|
||||
char i2cdatadst[I2C_DATA_LENGTH];
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
i2c_t i2cmaster;
|
||||
i2c_t i2cslave;
|
||||
#else
|
||||
volatile i2c_t i2cmaster;
|
||||
volatile i2c_t i2cslave;
|
||||
#endif
|
||||
|
||||
void i2c_callback(void *userdata)
|
||||
{
|
||||
|
||||
int i2clocalcnt;
|
||||
int result = 0;
|
||||
|
||||
DBG_8195A("show slave received data>>>\n");
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
|
||||
DBG_8195A("i2c data: %02x \t %02x\n",i2cdatadst[i2clocalcnt],i2cdatadst[i2clocalcnt+1]);
|
||||
}
|
||||
|
||||
// verify result
|
||||
result = 1;
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) {
|
||||
if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt]) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_8195A("\r\nResult is %s\r\n", (result) ? "success" : "fail");
|
||||
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i2clocalcnt;
|
||||
|
||||
int result = 0;
|
||||
|
||||
// prepare for transmission
|
||||
_memset(&i2cdatasrc[0], 0x00, I2C_DATA_LENGTH);
|
||||
_memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH);
|
||||
|
||||
for (i2clocalcnt=0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++){
|
||||
i2cdatasrc[i2clocalcnt] = i2clocalcnt+1;
|
||||
}
|
||||
#ifdef I2C_MASTER_DEVICE
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
#endif
|
||||
|
||||
#ifdef I2C_SLAVE_DEVICE
|
||||
i2c_init(&i2cslave, MBED_I2C_SLV_SDA ,MBED_I2C_SLV_SCL);
|
||||
i2c_frequency(&i2cslave,MBED_I2C_BUS_CLK);
|
||||
i2c_slave_address(&i2cslave, 0, MBED_I2C_SLAVE_ADDR0, 0xFF);
|
||||
i2c_slave_mode(&i2cslave, 1);
|
||||
i2c_set_user_callback(&i2cslave, I2C_RX_COMPLETE, i2c_callback);
|
||||
|
||||
DBG_8195A("slave read\n");
|
||||
i2c_slave_read(&i2cslave, &i2cdatadst[0], I2C_DATA_LENGTH);
|
||||
#endif
|
||||
|
||||
#ifdef I2C_MASTER_DEVICE
|
||||
DBG_8195A("master write...\n");
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], I2C_DATA_LENGTH, 1);
|
||||
#endif
|
||||
while(1){;}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Example Description
|
||||
|
||||
this example is use to measure atmos
|
||||
|
||||
work with arduino extended board, which has pressure sensor
|
||||
|
||||
the terminal will feedback real pressure value which is represented in Pa
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include "osdep_api.h"
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
//#include "rtl_lib.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
#define MBED_I2C_INTB PA_5
|
||||
#define MBED_I2C_SLAVE_ADDR0 0x5D
|
||||
#define MBED_I2C_BUS_CLK 40000 //hz
|
||||
#define I2C_DATA_MAX_LENGTH 20
|
||||
#define malloc pvPortMalloc
|
||||
#define free vPortFree
|
||||
|
||||
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
|
||||
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
|
||||
uint16_t cmd;
|
||||
|
||||
i2c_t i2cmaster;
|
||||
int count = 0;
|
||||
//sensor command
|
||||
#define SENSOR_START 0x20A0
|
||||
#define FIFO 0x2E41
|
||||
#define REBOOT 0x2110
|
||||
#define READ 0x2101
|
||||
#define BYPASS 0x2E00
|
||||
|
||||
|
||||
char i2cdatasrc[9] = {0x27, 0x28, 0x29, 0x2A};
|
||||
//char i2cdatasrc[7] = {0x40, 0x48, 0x50, 0x27, 0x28, 0x29, 0x2A};
|
||||
|
||||
|
||||
static void ePL_WriteCommand(uint16_t cmd)
|
||||
{
|
||||
i2cdata_write[0] = (uint8_t)(cmd >>8);
|
||||
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
|
||||
}
|
||||
/*
|
||||
struct node
|
||||
{
|
||||
int info;
|
||||
struct node *ptr;
|
||||
}*front,*rear,*temp,*front1;
|
||||
*/
|
||||
//int frontelement();
|
||||
//void enq(int data);
|
||||
//void deq();
|
||||
/*
|
||||
void enq(int data)
|
||||
{
|
||||
if (rear == NULL)
|
||||
{
|
||||
rear = (struct node *)malloc(1*sizeof(struct node));
|
||||
if(rear == NULL)
|
||||
{
|
||||
printf("\n\rmalloc rear failed!\n");
|
||||
return;
|
||||
}
|
||||
rear->ptr = NULL;
|
||||
rear->info = data;
|
||||
front = rear;
|
||||
//printf("front info: %d\n", front->info);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp=(struct node *)malloc(1*sizeof(struct node));
|
||||
rear->ptr = temp;
|
||||
temp->info = data;
|
||||
temp->ptr = NULL;
|
||||
|
||||
rear = temp;
|
||||
//printf("rear info: %d\n", rear->info);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
void deq()
|
||||
{
|
||||
front1 = front;
|
||||
//printf("front info before deq: %d\n", front->info);
|
||||
if (front1 == NULL)
|
||||
{
|
||||
printf("Error: Trying to display elements from empty queue\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (front1->ptr != NULL)
|
||||
{
|
||||
front1 = front1->ptr;
|
||||
//printf("\nDequed value : %d\n", front->info);
|
||||
free(front);
|
||||
front = front1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("\nDequed value : %d\n", front->info);
|
||||
free(front);
|
||||
front = NULL;
|
||||
rear = NULL;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
int result;
|
||||
int i, data;
|
||||
int temprature;
|
||||
int flag = 0;
|
||||
int sum = 0;
|
||||
int average = 0;
|
||||
struct node *output;
|
||||
char intertupt;
|
||||
|
||||
DiagPrintf("Sensor_Init \r\n");
|
||||
//for(i=0; i<16; i++)
|
||||
//printf("ouput before: %d\n", i2cdata_read[i]);
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
|
||||
ePL_WriteCommand(SENSOR_START);
|
||||
ePL_WriteCommand(REBOOT);
|
||||
//ePL_WriteCommand(BYPASS);
|
||||
|
||||
while(1){
|
||||
//i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[3], 1, 1);
|
||||
//i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[3], 2, 1);
|
||||
//printf("Status Reg: %d\n", i2cdata_read[3]);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1);
|
||||
//printf("--------pressure output LSB: %d\n", i2cdata_read[4]);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1);
|
||||
//printf("--------pressure output MID: %d\n", i2cdata_read[5]);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[3], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[3], 2, 1);
|
||||
//printf("--------pressure output MSB: %d\n", i2cdata_read[6]);
|
||||
Mdelay(2000);
|
||||
data = (i2cdata_read[3]*256*256*100+i2cdata_read[2]*256*100+i2cdata_read[1]*100)/4128;
|
||||
printf("pressure: %dPa\n", data);
|
||||
/*
|
||||
if(count == 20)
|
||||
{
|
||||
deq();
|
||||
}
|
||||
enq(data);
|
||||
output = front;
|
||||
sum = front->info;
|
||||
while(output->ptr != NULL)
|
||||
{
|
||||
output = output->ptr;
|
||||
sum = sum + output->info;
|
||||
}
|
||||
|
||||
//printf("------count = %d---------\n", count);
|
||||
average = sum / count;
|
||||
//printf("---final output: %d---\n", average);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
Mdelay(1000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*******************************************************************************
|
||||
HRM.h - Definition header
|
||||
*******************************************************************************/
|
||||
#ifndef HRM_H
|
||||
#define HRM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//------------------------------------------------------
|
||||
#define HR_SAMPLE_RATE 25// Hz
|
||||
#define HR_INTEG_MIN HR_INTEG_40
|
||||
#define HR_INTEG_BASE HR_INTEG_250
|
||||
#define HR_INTEG_MAX HR_INTEG_250
|
||||
|
||||
#define HR_TH_HIGH 63000
|
||||
#define HR_TH_LOW 30000
|
||||
//------------------------------------------------------
|
||||
|
||||
// HRM I2C address & register sub-addresses
|
||||
#define HR_SLAVE_ADDRESS 0x82
|
||||
|
||||
#define HR_FILTER_1 0<<5
|
||||
#define HR_FILTER_2 1<<5
|
||||
#define HR_FILTER_4 2<<5
|
||||
#define HR_FILTER_8 3<<5
|
||||
#define HR_FILTER_16 4<<5
|
||||
#define HR_FILTER_32 5<<5
|
||||
#define HR_FILTER_64 6<<5
|
||||
#define HR_FILTER_128 7<<5
|
||||
|
||||
#define HR_MODE_HR 1<<4
|
||||
#define HR_MODE_HRS 9<<4
|
||||
|
||||
#define HR_GAIN_MID 1
|
||||
#define HR_GAIN_LOW 3
|
||||
|
||||
#define HR_INTEG_20 5
|
||||
#define HR_INTEG_25 6
|
||||
#define HR_INTEG_30 7
|
||||
#define HR_INTEG_40 8
|
||||
#define HR_INTEG_55 9
|
||||
#define HR_INTEG_70 10
|
||||
#define HR_INTEG_90 11
|
||||
#define HR_INTEG_110 12
|
||||
#define HR_INTEG_150 13
|
||||
#define HR_INTEG_200 14
|
||||
#define HR_INTEG_250 15
|
||||
#define HR_INTEG_350 16
|
||||
#define HR_INTEG_450 17
|
||||
#define HR_INTEG_550 18
|
||||
|
||||
#define HR_OSR_64 0<<2
|
||||
#define HR_OSR_256 1<<2
|
||||
#define HR_OSR_1024 2<<2
|
||||
#define HR_OSR_2048 3<<2
|
||||
|
||||
#define HR_RESETN_RESET 0<<2
|
||||
#define HR_RESETN_RUN 1<<2
|
||||
|
||||
#define HR_PDRIVE_70MA 0<<4
|
||||
#define HR_PDRIVE_35MA 1<<4
|
||||
#define HR_PDRIVE_200MA 2<<4
|
||||
#define HR_PDRIVE_100MA 3<<4
|
||||
|
||||
#define HR_INT_FRAME 1<<2
|
||||
#define HR_INT_DISABLED 2<<2
|
||||
|
||||
#define HR_IR_DISABLE 0<<7
|
||||
#define HR_IR_ENABLE 1<<7
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
// Declarations
|
||||
void init_hrm(void);
|
||||
uint16_t read_hrm(void);
|
||||
|
||||
#endif /* HRM_H */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* heart_interface.h
|
||||
*
|
||||
* Created on: 2014/4/29
|
||||
* Author: 01004
|
||||
*/
|
||||
|
||||
#ifndef HEART_INTERFACE_H_
|
||||
#define HEART_INTERFACE_H_
|
||||
|
||||
#define MIN_HEART_RATE 48
|
||||
#define MAX_HEART_RATE 180
|
||||
|
||||
extern int g_heartrate;
|
||||
|
||||
typedef void (*hr_callback)(int);
|
||||
|
||||
/*
|
||||
* If there is no g-sensor, fill x, y, z in 0.
|
||||
*/
|
||||
void add_PPG_XYZ(int ppg, short xx, short yy, short zz);
|
||||
|
||||
/*
|
||||
* A callback to handle heartrate events.
|
||||
*/
|
||||
void register_callback(hr_callback callback);
|
||||
|
||||
/*
|
||||
* Ex: report_period = 25.
|
||||
* it means report a heart rate every 25 samples.
|
||||
*/
|
||||
void start(int report_period);
|
||||
|
||||
void reset(void);
|
||||
|
||||
void stop(void);
|
||||
|
||||
|
||||
#endif /* HEART_INTERFACE_H_ */
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Example Description
|
||||
|
||||
this example is use to measure heart rate of human
|
||||
|
||||
Requirement Components:
|
||||
extend board
|
||||
|
||||
work with arduino extended board, which has heart rate sensor
|
||||
|
||||
during the measurement, user has to lie his pulp on the sensor and do not rock the sensor
|
||||
|
||||
the test code will return back the heart rate
|
||||
|
||||
Build code
|
||||
1. Please be sure to copy inc\heart_interface.h, inc\HRM_2197.h
|
||||
2. Include hr_library.a in IAR project. Add hr_library.a into folder "lib" in IAR project.
|
||||
Binary file not shown.
|
|
@ -0,0 +1,162 @@
|
|||
/*******************************************************************************
|
||||
* HRM.c - Eminent Heart Rate Module (HRM) routines via I2C
|
||||
*******************************************************************************/
|
||||
#include "HRM_2197.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
//#include <windows.h>
|
||||
#include "heart_interface.h"
|
||||
#include "device.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include "osdep_api.h"
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
//#include "rtl_lib.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "main.h"
|
||||
|
||||
#define MBED_I2C_SLAVE_ADDR0 0x41
|
||||
#define HR_MODE 0x001b
|
||||
#define LED_ENABLE 0x3081
|
||||
#define FRAME_ENABLE 0x4804
|
||||
#define CHIP_RESET 0x4000
|
||||
#define CHIP_RUN 0x4004
|
||||
#define DATA_LOCK 0x4005
|
||||
#define DATA_UNLOCK 0x4004
|
||||
#define I2C_DATA_MAX_LENGTH 20
|
||||
#define CLOCK_SET 0x3800
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
#define MBED_I2C_INTB PA_5
|
||||
#define MBED_I2C_BUS_CLK 100000 //hz
|
||||
|
||||
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
|
||||
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
|
||||
uint16_t cmd;
|
||||
|
||||
i2c_t i2cmaster;
|
||||
|
||||
uint8_t integ_time = HR_INTEG_MIN;
|
||||
int integ_time_array[] = { 4, 6, 8, 10, 15, 20, 25, 30, 40, 55, 70, 90, 110, 150, 200, 250, 350, 450, 550 };
|
||||
|
||||
|
||||
|
||||
|
||||
//Step1. define the callback to handle event of heart rate update
|
||||
/*******************************************************************************
|
||||
* report heart rate every 1 second
|
||||
*******************************************************************************/
|
||||
void on_heartrate_update(int heartrate) {
|
||||
printf("heart rate %d\n", heartrate);
|
||||
//fflush(stdout);
|
||||
}
|
||||
|
||||
char i2cdatasrc[3] = {0x68, 0x90, 0x98};
|
||||
|
||||
|
||||
static void ePL_WriteCommand(uint16_t cmd)
|
||||
{
|
||||
i2cdata_write[0] = (uint8_t)(cmd >>8);
|
||||
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
|
||||
}
|
||||
|
||||
uint16_t read_hrm(void) {
|
||||
uint32_t raw, normalized_raw;
|
||||
int integ_time_changed = 0;
|
||||
ePL_WriteCommand(DATA_LOCK);
|
||||
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1);
|
||||
|
||||
raw = i2cdata_read[1];
|
||||
raw |= (uint16_t) i2cdata_read[2] << 8;
|
||||
|
||||
|
||||
normalized_raw = raw >> 4;
|
||||
normalized_raw = normalized_raw * integ_time_array[HR_INTEG_BASE];
|
||||
normalized_raw = normalized_raw / integ_time_array[integ_time];
|
||||
|
||||
if (raw > HR_TH_HIGH && integ_time > HR_INTEG_MIN) {
|
||||
integ_time -= 1;
|
||||
integ_time_changed = 1;
|
||||
} else if (raw < HR_TH_LOW && integ_time < HR_INTEG_MAX) {
|
||||
integ_time += 1;
|
||||
integ_time_changed = 1;
|
||||
}
|
||||
|
||||
if (integ_time_changed == 1) {
|
||||
|
||||
ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time));
|
||||
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET));
|
||||
}
|
||||
|
||||
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RUN));
|
||||
|
||||
return normalized_raw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* main function to read data, input to library,
|
||||
* and calculate heart rate
|
||||
*******************************************************************************/
|
||||
void main(void) {
|
||||
int i, length;
|
||||
int *data;
|
||||
uint16_t result;
|
||||
data = (int*) calloc(3000, sizeof(int));
|
||||
//load_ppg_signal(data, &length); //Load Test Data From File
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
//Step2. delegate the event of heart rate update
|
||||
register_callback(on_heartrate_update);
|
||||
|
||||
|
||||
|
||||
|
||||
//Step3. Set the data length of heart rate calculation= 2^9 = 512
|
||||
|
||||
ePL_WriteCommand(((0x00<<3)<<8) | ( HR_MODE_HRS | HR_OSR_1024 | HR_GAIN_MID));
|
||||
ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time));
|
||||
ePL_WriteCommand(((0x09<<3)<<8) | ( HR_PDRIVE_70MA));
|
||||
ePL_WriteCommand(((0x06<<3)<<8) | ( HR_IR_ENABLE | HR_INT_FRAME));
|
||||
ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET));
|
||||
while(1) {
|
||||
//Step4. Add ppg data continuously, and the Lib will return the Heart Rate 1 time/sec
|
||||
result = read_hrm();
|
||||
|
||||
if(result>100)
|
||||
add_PPG_XYZ(result, 0, 0, 0);
|
||||
|
||||
Mdelay(40); //Simulate the ppg input time interval = 40ms
|
||||
}
|
||||
|
||||
//Step5. Stop
|
||||
stop();
|
||||
|
||||
free(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* initialize ic parameters
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* read rawdata
|
||||
*******************************************************************************/
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use proximity sensor to detect lightness
|
||||
|
||||
Requirement Components:
|
||||
extend board
|
||||
|
||||
work with arduino extended board, which has proximity sensor
|
||||
|
||||
when the proximity sensor is in ALS mode (detect lightness), it will keep polling lightness output.
|
||||
|
||||
108
project/realtek_ameba1_va0_example/example_sources/i2c_epl2590_light/src/main.c
Executable file
108
project/realtek_ameba1_va0_example/example_sources/i2c_epl2590_light/src/main.c
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include "osdep_api.h"
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
//#include "rtl_lib.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
#define MBED_I2C_INTB PA_5
|
||||
#define MBED_I2C_SLAVE_ADDR0 0x49
|
||||
#define MBED_I2C_BUS_CLK 100000 //hz
|
||||
#define I2C_DATA_MAX_LENGTH 20
|
||||
|
||||
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
|
||||
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
|
||||
uint16_t cmd;
|
||||
|
||||
i2c_t i2cmaster;
|
||||
//sensor command
|
||||
#define WAKE_UP 0x1102
|
||||
#define CHIP_REFRESH1 0xFD8E
|
||||
#define CHIP_REFRESH2 0xFE22
|
||||
#define CHIP_REFRESH3 0xFE02
|
||||
#define CHIP_REFRESH4 0xFD00
|
||||
#define PS_MODE 0x0002
|
||||
#define ALS_MODE 0x0001
|
||||
#define POWER_UP 0x1102
|
||||
#define CHIP_RESET 0x1100
|
||||
#define CHANGE_TIME 0x0851
|
||||
#define SETTING_1 0x0F19
|
||||
#define SETTING_2 0x0D10
|
||||
#define INT 0x3022
|
||||
|
||||
char i2cdatasrc[5] = {0x1B, 0x15, 0x16, 0x80, 0x88};
|
||||
|
||||
|
||||
static void ePL_WriteCommand(uint16_t cmd)
|
||||
{
|
||||
i2cdata_write[0] = (uint8_t)(cmd >>8);
|
||||
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int result;
|
||||
int i;
|
||||
int light = 0;
|
||||
int flag = 0;
|
||||
char intertupt;
|
||||
|
||||
DiagPrintf("Sensor_Init \r\n");
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
|
||||
ePL_WriteCommand(WAKE_UP);
|
||||
ePL_WriteCommand(CHIP_REFRESH1);
|
||||
ePL_WriteCommand(CHIP_REFRESH2);
|
||||
ePL_WriteCommand(CHIP_REFRESH3);
|
||||
ePL_WriteCommand(CHIP_REFRESH4);
|
||||
|
||||
ePL_WriteCommand(ALS_MODE);
|
||||
|
||||
//ePL_WriteCommand(SETTING_1);
|
||||
//ePL_WriteCommand(SETTING_2);
|
||||
|
||||
|
||||
ePL_WriteCommand(CHIP_RESET);
|
||||
|
||||
ePL_WriteCommand(POWER_UP);
|
||||
Mdelay(240);
|
||||
while(1){
|
||||
//ePL_WriteCommand(DATA_LOCK);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 2, 1);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1);
|
||||
// printf("ALS LOW: %d\n", i2cdata_read[1]);
|
||||
//printf("ALS HIGH: %d\n", i2cdata_read[2]);
|
||||
light = i2cdata_read[1] + i2cdata_read[2] * 256;
|
||||
printf("lightness: %d\n", light);
|
||||
//flag = (i2cdata_read[0] & 8)? 1:0;
|
||||
//int ret = (i2cdata_read[0] & 4)? 1:0;
|
||||
//printf("flag: %d\n", flag);
|
||||
//printf("ret: %d\n", ret);
|
||||
|
||||
//ePL_WriteCommand(POWER_UP);
|
||||
Mdelay(1000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use proximity sensor to detect distance
|
||||
|
||||
Requirement Components:
|
||||
extend board
|
||||
|
||||
work with arduino extended board, which has proximity sensor
|
||||
|
||||
When the proximity sensor is in PS mode (detect distance), if the object is close to the sensor, a near message will print out. Otherwise a far message will print out.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include "osdep_api.h"
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
//#include "rtl_lib.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MBED_I2C_MTR_SDA PB_3
|
||||
#define MBED_I2C_MTR_SCL PB_2
|
||||
#define MBED_I2C_INTB PA_5
|
||||
#define MBED_I2C_SLAVE_ADDR0 0x49
|
||||
#define MBED_I2C_BUS_CLK 100000 //hz
|
||||
#define I2C_DATA_MAX_LENGTH 20
|
||||
|
||||
uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
|
||||
uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
|
||||
uint16_t cmd;
|
||||
|
||||
i2c_t i2cmaster;
|
||||
//sensor command
|
||||
#define WAKE_UP 0x1102
|
||||
#define CHIP_REFRESH1 0xFD8E
|
||||
#define CHIP_REFRESH2 0xFE22
|
||||
#define CHIP_REFRESH3 0xFE02
|
||||
#define CHIP_REFRESH4 0xFD00
|
||||
#define PS_MODE 0x0002
|
||||
#define ALS1_MODE 0x0072
|
||||
#define ALS2_MODE 0x503E
|
||||
#define ALS3_MODE 0x583E
|
||||
#define POWER_UP 0x1102
|
||||
#define CHIP_RESET 0x1100
|
||||
#define CHANGE_TIME 0x0851
|
||||
#define SETTING_1 0x0F19
|
||||
#define SETTING_2 0x0D10
|
||||
#define INT 0x3022
|
||||
|
||||
char i2cdatasrc[5] = {0x1B, 0x1E, 0x1F, 0x80, 0x88};
|
||||
|
||||
|
||||
static void ePL_WriteCommand(uint16_t cmd)
|
||||
{
|
||||
i2cdata_write[0] = (uint8_t)(cmd >>8);
|
||||
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int result;
|
||||
int i;
|
||||
int flag = 0;
|
||||
char intertupt;
|
||||
|
||||
DiagPrintf("Sensor_Init \r\n");
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
|
||||
ePL_WriteCommand(WAKE_UP);
|
||||
ePL_WriteCommand(CHIP_REFRESH1);
|
||||
ePL_WriteCommand(CHIP_REFRESH2);
|
||||
ePL_WriteCommand(CHIP_REFRESH3);
|
||||
ePL_WriteCommand(CHIP_REFRESH4);
|
||||
|
||||
ePL_WriteCommand(PS_MODE);
|
||||
|
||||
ePL_WriteCommand(SETTING_1);
|
||||
ePL_WriteCommand(SETTING_2);
|
||||
|
||||
|
||||
ePL_WriteCommand(CHIP_RESET);
|
||||
|
||||
ePL_WriteCommand(POWER_UP);
|
||||
Mdelay(240);
|
||||
while(1){
|
||||
//ePL_WriteCommand(DATA_LOCK);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 2, 1);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1);
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1);
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1);
|
||||
//printf("PS LOW: %d\n", i2cdata_read[1]);
|
||||
//printf("PS HIGH: %d\n", i2cdata_read[2]);
|
||||
flag = (i2cdata_read[0] & 8)? 1:0;
|
||||
int ret = (i2cdata_read[0] & 4)? 1:0;
|
||||
//printf("flag: %d\n", flag);
|
||||
//printf("ret: %d\n", ret);
|
||||
|
||||
if(flag){
|
||||
printf("the object is far\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("the object is near\n");
|
||||
}
|
||||
|
||||
//ePL_WriteCommand(POWER_UP);
|
||||
Mdelay(1000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
10
project/realtek_ameba1_va0_example/example_sources/i2s/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/i2s/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2s by using mbed extend api
|
||||
|
||||
1.Plug ALC5651 shield to Ameba HDK
|
||||
|
||||
2.Run the main function.
|
||||
|
||||
3.Plug earphone to Green phone jack
|
||||
|
||||
183
project/realtek_ameba1_va0_example/example_sources/i2s/src/alc5651.c
Executable file
183
project/realtek_ameba1_va0_example/example_sources/i2s/src/alc5651.c
Executable file
|
|
@ -0,0 +1,183 @@
|
|||
#include <stdio.h>
|
||||
#include "PinNames.h"
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include <osdep_api.h>
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
//#define I2C_MTR_SDA PC_4//PB_3
|
||||
//#define I2C_MTR_SCL PC_5//PB_2
|
||||
#define I2C_MTR_SDA PB_3
|
||||
#define I2C_MTR_SCL PB_2
|
||||
#define I2C_BUS_CLK 100000 //hz
|
||||
|
||||
#define I2C_ALC5651_ADDR (0x34/2)
|
||||
|
||||
#define RT5651_PRIV_INDEX 0x6a
|
||||
#define RT5651_PRIV_DATA 0x6c
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
i2c_t alc5651_i2c;
|
||||
#else
|
||||
volatile i2c_t alc5651_i2c;
|
||||
#define printf DBG_8195A
|
||||
#endif
|
||||
|
||||
static void alc5651_delay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i=10000;
|
||||
while (i) {
|
||||
i--;
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
}
|
||||
|
||||
void alc5651_reg_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
char buf[4];
|
||||
buf[0] = (char)reg;
|
||||
buf[1] = (char)(value>>8);
|
||||
buf[2] = (char)(value&0xff);
|
||||
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
|
||||
alc5651_delay();
|
||||
}
|
||||
|
||||
void alc5651_reg_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
int tmp;
|
||||
char *buf = (char*)&tmp;
|
||||
|
||||
buf[0] = (char)reg;
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
|
||||
alc5651_delay();
|
||||
|
||||
buf[0] = 0xaa;
|
||||
buf[1] = 0xaa;
|
||||
|
||||
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
|
||||
alc5651_delay();
|
||||
|
||||
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
|
||||
}
|
||||
|
||||
void alc5651_index_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_write(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_index_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_read(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_reg_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec reg dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_reg_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_index_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec index dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_index_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_init(void)
|
||||
{
|
||||
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
|
||||
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
|
||||
}
|
||||
|
||||
void alc5651_set_word_len(int len_idx) // interface2
|
||||
{
|
||||
// 0: 16 1: 20 2: 24 3: 8
|
||||
unsigned int val;
|
||||
alc5651_reg_read(0x71,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x71,val);
|
||||
alc5651_reg_read(0x70,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x70,val);
|
||||
|
||||
}
|
||||
|
||||
void alc5651_init_interface1(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x27,0x3820);
|
||||
alc5651_reg_write(0x77,0x0000);
|
||||
}
|
||||
|
||||
void alc5651_init_interface2(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x28,0x3030);
|
||||
alc5651_reg_write(0x2F,0x0080);
|
||||
}
|
||||
8041
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_11025_2ch_16b.c
Executable file
8041
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_11025_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
11666
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_16000_2ch_16b.c
Executable file
11666
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_16000_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
16075
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_22050_2ch_16b.c
Executable file
16075
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_22050_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
17496
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_24000_2ch_16b.c
Executable file
17496
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_24000_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
23326
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_32000_2ch_16b.c
Executable file
23326
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_32000_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
32143
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_44100_2ch_16b.c
Executable file
32143
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_44100_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
34985
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_48000_2ch_16b.c
Executable file
34985
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_48000_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
5836
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_8000_2ch_16b.c
Executable file
5836
project/realtek_ameba1_va0_example/example_sources/i2s/src/birds_8000_2ch_16b.c
Executable file
File diff suppressed because it is too large
Load diff
326
project/realtek_ameba1_va0_example/example_sources/i2s/src/main.c
Executable file
326
project/realtek_ameba1_va0_example/example_sources/i2s/src/main.c
Executable file
|
|
@ -0,0 +1,326 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "i2s_api.h"
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#include "alc5651.c"
|
||||
/*
|
||||
extern void alc5651_init(void);
|
||||
extern void alc5651_init_interface2(void);
|
||||
extern void alc5651_reg_dump(void);
|
||||
extern void alc5651_index_dump(void);
|
||||
extern void alc5651_set_word_len(int len_idx);
|
||||
*/
|
||||
i2s_t i2s_obj;
|
||||
|
||||
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
|
||||
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
|
||||
|
||||
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
|
||||
#define SAMPLE_FILE
|
||||
#define SAMPLE_FILE_RATE 44100
|
||||
#define SAMPLE_FILE_CHNUM 2
|
||||
|
||||
#define I2S_SCLK_PIN PC_1
|
||||
#define I2S_WS_PIN PC_0
|
||||
#define I2S_SD_PIN PC_2
|
||||
|
||||
#if defined(SAMPLE_FILE)
|
||||
// no sample
|
||||
// SR_96KHZ,
|
||||
// SR_7p35KHZ,
|
||||
// SR_29p4KHZ,
|
||||
// SR_88p2KHZ
|
||||
#if SAMPLE_FILE_RATE==8000
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_8000_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_8KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==11025
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_11025_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_11p02KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==16000
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_16000_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_16KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==22050
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_22050_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_22p05KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==24000
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_24000_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_24KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==32000
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_32000_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_32KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==44100
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_44100_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_44p1KHZ
|
||||
#endif
|
||||
#elif SAMPLE_FILE_RATE==48000
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_48000_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_48KHZ
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#undef SAMPLE_FILE_CHNUM
|
||||
#define SAMPLE_FILE_CHNUM CH_STEREO
|
||||
#endif
|
||||
|
||||
int curr_cnt=0;
|
||||
#else
|
||||
|
||||
short test_sine16[16]={0, 12539/4, 23170/4, 30273/4, 32767/4, 30273/4, 23170/4, 12539/4,
|
||||
0, -12539/4, -23170/4, -30273/4, -32767/4, -30273/4, -23170/4, -12539/4};
|
||||
int test_sine24[16]={0, 12539*256/4, 23170*256/4, 30273*256/4, 32767*256/4, 30273*256/4, 23170*256/4, 12539*256/4,
|
||||
0, -12539*256/4, -23170*256/4, -30273*256/4, -32767*256/4, -30273*256/4, -23170*256/4, -12539*256/4};
|
||||
|
||||
extern void wait_ms(u32);
|
||||
|
||||
#include <math.h>
|
||||
short remap_level_to_signed_16_bit(float val)
|
||||
{
|
||||
val*=32767;
|
||||
if(val>32767) val=32767;
|
||||
if(val<-32768) val=-32768;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void generate_freq_16bit(short *buffer, int count, float freq, float sampling_rate)
|
||||
{
|
||||
int pos; // sample number we're on
|
||||
|
||||
for (pos = 0; pos < count; pos++) {
|
||||
float a = 2 * 3.14159f * freq * pos / sampling_rate;
|
||||
// convert from [-1.0,1.0] to [-32767,32767]:
|
||||
buffer[pos] = remap_level_to_signed_16_bit(a);
|
||||
}
|
||||
}
|
||||
|
||||
void gen_sound_sample16(short *buf, int buf_size, int channel_num)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < buf_size ; i+=channel_num){
|
||||
buf[i] = test_sine16[(i/channel_num)%16];
|
||||
if(channel_num>=2)
|
||||
buf[i+1] = test_sine16[(i/channel_num)%16];
|
||||
}
|
||||
}
|
||||
|
||||
void gen_sound_sample24(int *buf, int buf_size, int channel_num)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < buf_size ; i+=channel_num){
|
||||
buf[i] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
|
||||
if(channel_num>=2)
|
||||
//buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
|
||||
buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void test_delay(int sec)
|
||||
{
|
||||
for(int i=0;i<166*1000*100*sec;i++)
|
||||
asm(" nop");
|
||||
}
|
||||
#endif
|
||||
|
||||
int test_rate_list[12] = {
|
||||
SR_8KHZ,
|
||||
SR_16KHZ,
|
||||
SR_24KHZ,
|
||||
SR_32KHZ,
|
||||
SR_48KHZ,
|
||||
SR_96KHZ,
|
||||
SR_7p35KHZ,
|
||||
SR_11p02KHZ,
|
||||
SR_22p05KHZ,
|
||||
SR_29p4KHZ,
|
||||
SR_44p1KHZ,
|
||||
SR_88p2KHZ
|
||||
};
|
||||
#endif
|
||||
|
||||
void test_tx_complete(void *data, char *pbuf)
|
||||
{
|
||||
int *ptx_buf;
|
||||
|
||||
i2s_t *obj = (i2s_t *)data;
|
||||
static u32 count=0;
|
||||
//DBG_8195A_I2S_LVL(VERI_I2S_LVL, "I2S%d %s\n",pI2SDemoHnd->DevNum,__func__);
|
||||
count++;
|
||||
if ((count&1023) == 1023)
|
||||
{
|
||||
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ",\n");
|
||||
}
|
||||
|
||||
ptx_buf = i2s_get_tx_page(obj);
|
||||
//ptx_buf = (int*)pbuf;
|
||||
#if defined(SAMPLE_FILE)
|
||||
_memcpy((void*)ptx_buf, (void*)&sample[curr_cnt], I2S_DMA_PAGE_SIZE);
|
||||
curr_cnt+=(I2S_DMA_PAGE_SIZE/sizeof(short));
|
||||
if(curr_cnt >= sample_size*(obj->channel_num==CH_MONO?1:2)) {
|
||||
curr_cnt = 0;
|
||||
}
|
||||
#else
|
||||
if(obj->word_length == WL_16b){
|
||||
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), obj->channel_num==CH_MONO?1:2);
|
||||
}else{
|
||||
gen_sound_sample24((int*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(int), obj->channel_num==CH_MONO?1:2);
|
||||
}
|
||||
#endif
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf);
|
||||
}
|
||||
|
||||
void test_rx_complete(void *data, char* pbuf)
|
||||
{
|
||||
i2s_t *obj = (i2s_t *)data;
|
||||
int *ptx_buf;
|
||||
|
||||
static u32 count=0;
|
||||
count++;
|
||||
if ((count&1023) == 1023)
|
||||
{
|
||||
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n");
|
||||
}
|
||||
|
||||
ptx_buf = i2s_get_tx_page(obj);
|
||||
_memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE);
|
||||
i2s_recv_page(obj); // submit a new page for receive
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int *ptx_buf;
|
||||
int i,j;
|
||||
|
||||
alc5651_init();
|
||||
alc5651_init_interface2(); // connect to ALC interface 2
|
||||
|
||||
// dump register
|
||||
//alc5651_reg_dump();
|
||||
//alc5651_index_dump();
|
||||
|
||||
// I2S init
|
||||
i2s_obj.channel_num = CH_MONO;//CH_STEREO;
|
||||
i2s_obj.sampling_rate = SR_44p1KHZ;
|
||||
i2s_obj.word_length = WL_16b;
|
||||
i2s_obj.direction = I2S_DIR_TXRX;
|
||||
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
|
||||
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
|
||||
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
|
||||
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
|
||||
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
|
||||
|
||||
#if defined(SAMPLE_FILE)
|
||||
i2s_set_param(&i2s_obj,SAMPLE_FILE_CHNUM,SAMPLE_FILE_RATE,WL_16b);
|
||||
for (i=0;i<I2S_DMA_PAGE_NUM;i++) {
|
||||
ptx_buf = i2s_get_tx_page(&i2s_obj);
|
||||
if (ptx_buf) {
|
||||
_memcpy((void*)ptx_buf, (void*)&sample[curr_cnt], I2S_DMA_PAGE_SIZE);
|
||||
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
|
||||
curr_cnt+=(I2S_DMA_PAGE_SIZE/sizeof(short));
|
||||
if(curr_cnt >= sample_size*(i2s_obj.channel_num==CH_MONO?1:2)) {
|
||||
curr_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
// output freq, @ sampling rate
|
||||
// 6kHz @ 96kHz
|
||||
// 3kHz @ 48kHz
|
||||
// 2kHz @ 32kHz
|
||||
// 1.5kHz @ 24kHz
|
||||
// 1kHz @ 16kHz
|
||||
// 500Hz @ 8kHz
|
||||
// 5512.5 Hz @ 88200Hz
|
||||
// 2756.25 Hz @ 44100Hz
|
||||
// 1837.5 Hz @ 29400Hz
|
||||
// 1378.125 Hz @ 22050Hz
|
||||
// 459.375 Hz @ 7350Hz
|
||||
|
||||
// Stereo, 16bit
|
||||
for(i=0;i<12;i++){
|
||||
i2s_set_param(&i2s_obj,CH_STEREO,test_rate_list[i],WL_16b);
|
||||
// Start with fill all pages of DMA buffer
|
||||
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
|
||||
ptx_buf = i2s_get_tx_page(&i2s_obj);
|
||||
if (ptx_buf) {
|
||||
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), 2);
|
||||
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
|
||||
}
|
||||
}
|
||||
wait_ms(5000); // delay 5 sec.
|
||||
}
|
||||
|
||||
// Mono, 16bit
|
||||
for(i=0;i<12;i++){
|
||||
i2s_set_param(&i2s_obj,CH_MONO,test_rate_list[i],WL_16b);
|
||||
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
|
||||
ptx_buf = i2s_get_tx_page(&i2s_obj);
|
||||
if (ptx_buf) {
|
||||
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), 1);
|
||||
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
|
||||
}
|
||||
}
|
||||
wait_ms(5000); // delay 5 sec.
|
||||
}
|
||||
|
||||
// i2s_deinit(&i2s_obj);
|
||||
i2s_disable(&i2s_obj);
|
||||
|
||||
alc5651_set_word_len(2);
|
||||
alc5651_reg_dump();
|
||||
|
||||
i2s_enable(&i2s_obj);
|
||||
// Stereo, 24bit
|
||||
for(i=0;i<12;i++){
|
||||
i2s_set_param(&i2s_obj,CH_STEREO,test_rate_list[i],WL_24b);
|
||||
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
|
||||
ptx_buf = i2s_get_tx_page(&i2s_obj);
|
||||
if (ptx_buf) {
|
||||
gen_sound_sample24((int*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(int), 2);
|
||||
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
|
||||
}
|
||||
}
|
||||
wait_ms(5000); // delay 5 sec.
|
||||
}
|
||||
|
||||
// Not Support Mono, 24bit
|
||||
i2s_deinit(&i2s_obj);
|
||||
#endif
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
||||
15
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/readme.txt
Executable file
15
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/readme.txt
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2s by using mbed extend api
|
||||
Use TXRX mode to archive software bypass mode
|
||||
|
||||
NOTE: RX need clock generated by TX. This mode can do TX/RX in the same time.
|
||||
|
||||
1.Plug ALC5651 shield to Ameba HDK
|
||||
|
||||
2.Run the main function.
|
||||
|
||||
3.Plug earphone to Green phone jack
|
||||
|
||||
4.Plug audio source to Red phone jack
|
||||
|
||||
183
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/alc5651.c
Executable file
183
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/alc5651.c
Executable file
|
|
@ -0,0 +1,183 @@
|
|||
#include <stdio.h>
|
||||
#include "PinNames.h"
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include <osdep_api.h>
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
//#define I2C_MTR_SDA PC_4//PB_3
|
||||
//#define I2C_MTR_SCL PC_5//PB_2
|
||||
#define I2C_MTR_SDA PB_3
|
||||
#define I2C_MTR_SCL PB_2
|
||||
#define I2C_BUS_CLK 100000 //hz
|
||||
|
||||
#define I2C_ALC5651_ADDR (0x34/2)
|
||||
|
||||
#define RT5651_PRIV_INDEX 0x6a
|
||||
#define RT5651_PRIV_DATA 0x6c
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
i2c_t alc5651_i2c;
|
||||
#else
|
||||
volatile i2c_t alc5651_i2c;
|
||||
#define printf DBG_8195A
|
||||
#endif
|
||||
|
||||
static void alc5651_delay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i=10000;
|
||||
while (i) {
|
||||
i--;
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
}
|
||||
|
||||
void alc5651_reg_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
char buf[4];
|
||||
buf[0] = (char)reg;
|
||||
buf[1] = (char)(value>>8);
|
||||
buf[2] = (char)(value&0xff);
|
||||
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
|
||||
alc5651_delay();
|
||||
}
|
||||
|
||||
void alc5651_reg_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
int tmp;
|
||||
char *buf = (char*)&tmp;
|
||||
|
||||
buf[0] = (char)reg;
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
|
||||
alc5651_delay();
|
||||
|
||||
buf[0] = 0xaa;
|
||||
buf[1] = 0xaa;
|
||||
|
||||
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
|
||||
alc5651_delay();
|
||||
|
||||
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
|
||||
}
|
||||
|
||||
void alc5651_index_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_write(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_index_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_read(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_reg_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec reg dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_reg_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_index_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec index dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_index_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_init(void)
|
||||
{
|
||||
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
|
||||
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
|
||||
}
|
||||
|
||||
void alc5651_set_word_len(int len_idx) // interface2
|
||||
{
|
||||
// 0: 16 1: 20 2: 24 3: 8
|
||||
unsigned int val;
|
||||
alc5651_reg_read(0x71,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x71,val);
|
||||
alc5651_reg_read(0x70,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x70,val);
|
||||
|
||||
}
|
||||
|
||||
void alc5651_init_interface1(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x27,0x3820);
|
||||
alc5651_reg_write(0x77,0x0000);
|
||||
}
|
||||
|
||||
void alc5651_init_interface2(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x28,0x3030);
|
||||
alc5651_reg_write(0x2F,0x0080);
|
||||
}
|
||||
80
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/main.c
Executable file
80
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/main.c
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
/* This is software bypass example */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "i2s_api.h"
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#include "alc5651.c"
|
||||
|
||||
i2s_t i2s_obj;
|
||||
|
||||
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
|
||||
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
|
||||
|
||||
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
|
||||
#define I2S_SCLK_PIN PC_1
|
||||
#define I2S_WS_PIN PC_0
|
||||
#define I2S_SD_PIN PC_2
|
||||
|
||||
void test_tx_complete(void *data, char *pbuf)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
void test_rx_complete(void *data, char* pbuf)
|
||||
{
|
||||
i2s_t *obj = (i2s_t *)data;
|
||||
int *ptx_buf;
|
||||
|
||||
static u32 count=0;
|
||||
count++;
|
||||
if ((count&1023) == 1023)
|
||||
{
|
||||
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n");
|
||||
}
|
||||
|
||||
ptx_buf = i2s_get_tx_page(obj);
|
||||
_memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE);
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
|
||||
i2s_recv_page(obj); // submit a new page for receive
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int *ptx_buf;
|
||||
int i,j;
|
||||
|
||||
alc5651_init();
|
||||
alc5651_init_interface2(); // connect to ALC interface 2
|
||||
|
||||
// dump register
|
||||
//alc5651_reg_dump();
|
||||
//alc5651_index_dump();
|
||||
|
||||
// I2S init
|
||||
i2s_obj.channel_num = CH_STEREO;
|
||||
i2s_obj.sampling_rate = SR_44p1KHZ;
|
||||
i2s_obj.word_length = WL_16b;
|
||||
i2s_obj.direction = I2S_DIR_TXRX;
|
||||
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
|
||||
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
|
||||
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
|
||||
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
|
||||
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
|
||||
|
||||
/* rx need clock, let tx out first */
|
||||
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));
|
||||
i2s_recv_page(&i2s_obj);
|
||||
|
||||
while(1);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2s by using mbed extend api
|
||||
|
||||
Using TX only and RX only mode.
|
||||
RX will fill buffer until full then switching to TX only mode to play buffer content.
|
||||
|
||||
1.Plug ALC5651 shield to Ameba HDK
|
||||
|
||||
2.Run the main function.
|
||||
|
||||
3.Plug earphone to Green phone jack
|
||||
|
||||
4.Plug audio source to Red phone jack
|
||||
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
#include <stdio.h>
|
||||
#include "PinNames.h"
|
||||
#include "basic_types.h"
|
||||
#include "diag.h"
|
||||
#include <osdep_api.h>
|
||||
|
||||
#include "i2c_api.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
//#define I2C_MTR_SDA PC_4//PB_3
|
||||
//#define I2C_MTR_SCL PC_5//PB_2
|
||||
#define I2C_MTR_SDA PB_3
|
||||
#define I2C_MTR_SCL PB_2
|
||||
#define I2C_BUS_CLK 100000 //hz
|
||||
|
||||
#define I2C_ALC5651_ADDR (0x34/2)
|
||||
|
||||
#define RT5651_PRIV_INDEX 0x6a
|
||||
#define RT5651_PRIV_DATA 0x6c
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
i2c_t alc5651_i2c;
|
||||
#else
|
||||
volatile i2c_t alc5651_i2c;
|
||||
#define printf DBG_8195A
|
||||
#endif
|
||||
|
||||
static void alc5651_delay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i=10000;
|
||||
while (i) {
|
||||
i--;
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
}
|
||||
|
||||
void alc5651_reg_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
char buf[4];
|
||||
buf[0] = (char)reg;
|
||||
buf[1] = (char)(value>>8);
|
||||
buf[2] = (char)(value&0xff);
|
||||
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
|
||||
alc5651_delay();
|
||||
}
|
||||
|
||||
void alc5651_reg_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
int tmp;
|
||||
char *buf = (char*)&tmp;
|
||||
|
||||
buf[0] = (char)reg;
|
||||
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
|
||||
alc5651_delay();
|
||||
|
||||
buf[0] = 0xaa;
|
||||
buf[1] = 0xaa;
|
||||
|
||||
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
|
||||
alc5651_delay();
|
||||
|
||||
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
|
||||
}
|
||||
|
||||
void alc5651_index_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_write(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_index_read(unsigned int reg, unsigned int *value)
|
||||
{
|
||||
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
|
||||
alc5651_reg_read(RT5651_PRIV_DATA, value);
|
||||
}
|
||||
|
||||
void alc5651_reg_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec reg dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_reg_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_index_dump(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int value;
|
||||
|
||||
printf("alc5651 codec index dump\n\r");
|
||||
printf("------------------------\n\r");
|
||||
for(i=0;i<=0xff;i++){
|
||||
alc5651_index_read(i, &value);
|
||||
printf("%02x : %04x\n\r", i, (unsigned short)value);
|
||||
}
|
||||
printf("------------------------\n\r");
|
||||
}
|
||||
|
||||
void alc5651_init(void)
|
||||
{
|
||||
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
|
||||
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
|
||||
}
|
||||
|
||||
void alc5651_set_word_len(int len_idx) // interface2
|
||||
{
|
||||
// 0: 16 1: 20 2: 24 3: 8
|
||||
unsigned int val;
|
||||
alc5651_reg_read(0x71,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x71,val);
|
||||
alc5651_reg_read(0x70,&val);
|
||||
val &= (~(0x3<<2));
|
||||
val |= (len_idx<<2);
|
||||
alc5651_reg_write(0x70,val);
|
||||
|
||||
}
|
||||
|
||||
void alc5651_init_interface1(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x27,0x3820);
|
||||
alc5651_reg_write(0x77,0x0000);
|
||||
}
|
||||
|
||||
void alc5651_init_interface2(void)
|
||||
{
|
||||
alc5651_reg_write(0x00,0x0021);
|
||||
alc5651_reg_write(0x63,0xE8FE);
|
||||
alc5651_reg_write(0x61,0x5800);
|
||||
alc5651_reg_write(0x62,0x0C00);
|
||||
alc5651_reg_write(0x73,0x0000);
|
||||
alc5651_reg_write(0x2A,0x4242);
|
||||
alc5651_reg_write(0x45,0x2000);
|
||||
alc5651_reg_write(0x02,0x4848);
|
||||
alc5651_reg_write(0x8E,0x0019);
|
||||
alc5651_reg_write(0x8F,0x3100);
|
||||
alc5651_reg_write(0x91,0x0E00);
|
||||
alc5651_index_write(0x3D,0x3E00);
|
||||
alc5651_reg_write(0xFA,0x0011);
|
||||
alc5651_reg_write(0x83,0x0800);
|
||||
alc5651_reg_write(0x84,0xA000);
|
||||
alc5651_reg_write(0xFA,0x0C11);
|
||||
alc5651_reg_write(0x64,0x4010);
|
||||
alc5651_reg_write(0x65,0x0C00);
|
||||
alc5651_reg_write(0x61,0x5806);
|
||||
alc5651_reg_write(0x62,0xCC00);
|
||||
alc5651_reg_write(0x3C,0x004F);
|
||||
alc5651_reg_write(0x3E,0x004F);
|
||||
alc5651_reg_write(0x28,0x3030);
|
||||
alc5651_reg_write(0x2F,0x0080);
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/* This is RX only and TX only example */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "i2s_api.h"
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#include "alc5651.c"
|
||||
|
||||
i2s_t i2s_obj;
|
||||
|
||||
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
|
||||
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
|
||||
|
||||
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
|
||||
#define RECV_PAGE_NUM 50
|
||||
u8 recv_buf[I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM];
|
||||
|
||||
#define I2S_SCLK_PIN PC_1
|
||||
#define I2S_WS_PIN PC_0
|
||||
#define I2S_SD_PIN PC_2
|
||||
|
||||
u32 count = 0;
|
||||
void test_tx_complete(void *data, char *pbuf)
|
||||
{
|
||||
i2s_t *obj = (i2s_t *)data;
|
||||
int *ptx_buf;
|
||||
|
||||
if(count < RECV_PAGE_NUM){
|
||||
ptx_buf = i2s_get_tx_page(obj);
|
||||
_memcpy((void*)ptx_buf, (void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], I2S_DMA_PAGE_SIZE);
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf);
|
||||
count++;
|
||||
}else{
|
||||
count = 0;
|
||||
i2s_set_direction(obj, I2S_DIR_RX);
|
||||
i2s_recv_page(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void test_rx_complete(void *data, char* pbuf)
|
||||
{
|
||||
i2s_t *obj = (i2s_t *)data;
|
||||
int *ptx_buf;
|
||||
|
||||
if(count < RECV_PAGE_NUM){
|
||||
_memcpy((void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], (void*)pbuf, I2S_DMA_PAGE_SIZE);
|
||||
count++;
|
||||
i2s_recv_page(obj);
|
||||
}else{
|
||||
count = 1;
|
||||
i2s_set_direction(obj, I2S_DIR_TX);
|
||||
ptx_buf = i2s_get_tx_page(obj);
|
||||
_memcpy((void*)ptx_buf, (void*)recv_buf, I2S_DMA_PAGE_SIZE);
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int *ptx_buf;
|
||||
int i,j;
|
||||
|
||||
alc5651_init();
|
||||
alc5651_init_interface2(); // connect to ALC interface 2
|
||||
|
||||
// dump register
|
||||
//alc5651_reg_dump();
|
||||
//alc5651_index_dump();
|
||||
|
||||
// I2S init
|
||||
i2s_obj.channel_num = CH_MONO;
|
||||
i2s_obj.sampling_rate = SR_16KHZ;
|
||||
i2s_obj.word_length = WL_16b;
|
||||
i2s_obj.direction = I2S_DIR_RX;
|
||||
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
|
||||
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
|
||||
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
|
||||
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
|
||||
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
|
||||
|
||||
i2s_recv_page(&i2s_obj);
|
||||
|
||||
while(1);
|
||||
|
||||
}
|
||||
28
project/realtek_ameba1_va0_example/example_sources/nfc/readme.txt
Executable file
28
project/realtek_ameba1_va0_example/example_sources/nfc/readme.txt
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use nfc interface.
|
||||
|
||||
Requirement Components:
|
||||
1. nfc reader.
|
||||
Ex. Smart phone which has NFC reader. In Android, you can use below app
|
||||
|
||||
NFC Tag reader
|
||||
https://play.google.com/store/apps/details?id=com.nxp.taginfolite
|
||||
|
||||
NFC Tag reader & writer
|
||||
https://play.google.com/store/apps/details?id=com.wakdev.wdnfc
|
||||
|
||||
NFC tag writer
|
||||
https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter
|
||||
|
||||
2. Connect NFC antenna.
|
||||
By default the NFC antenna is provided but not connected.
|
||||
You can choose your desired antenna and weld it on the board
|
||||
|
||||
|
||||
Verification Steps:
|
||||
(a) Open nfc reader app, Tap phone on NFC antenna, then the ndef message content is text "HELLO WORLD!"
|
||||
(b) Open nfc writer app, write something to the tag. (Ex. text message "abcdefg")
|
||||
It'll also dump raw data on the log.
|
||||
(c) Open nfc reader app, tap phone on NFC antenna, and check if the conten is exactly the same as previous move.
|
||||
|
||||
214
project/realtek_ameba1_va0_example/example_sources/nfc/src/main.c
Executable file
214
project/realtek_ameba1_va0_example/example_sources/nfc/src/main.c
Executable file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "nfc_api.h"
|
||||
#include "flash_api.h"
|
||||
|
||||
#define NFC_RESTORE_DEFAULT (0)
|
||||
|
||||
#define NFC_MAX_PAGE_NUM 36
|
||||
nfctag_t nfctag;
|
||||
unsigned int nfc_tag_content[NFC_MAX_PAGE_NUM];
|
||||
unsigned char nfc_tag_dirty[NFC_MAX_PAGE_NUM];
|
||||
|
||||
#define RTK_NFC_UID 0x58
|
||||
unsigned char nfc_default_uid[7] = {
|
||||
RTK_NFC_UID, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
|
||||
};
|
||||
|
||||
osThreadId nfc_tid = 0;
|
||||
|
||||
#define FLASH_APP_NFC_BASE 0x85000
|
||||
flash_t flash_nfc;
|
||||
|
||||
void nfc_event_listener(void *arg, unsigned int event) {
|
||||
switch(event) {
|
||||
case NFC_EV_READER_PRESENT:
|
||||
DiagPrintf("NFC_EV_READER_PRESENT\r\n");
|
||||
break;
|
||||
case NFC_EV_READ:
|
||||
DiagPrintf("NFC_EV_READ\r\n");
|
||||
break;
|
||||
case NFC_EV_WRITE:
|
||||
DiagPrintf("NFC_EV_WRITE\r\n");
|
||||
break;
|
||||
case NFC_EV_ERR:
|
||||
DiagPrintf("NFC_EV_ERR\r\n");
|
||||
break;
|
||||
case NFC_EV_CACHE_READ:
|
||||
DiagPrintf("NFC_EV_CACHE_READ\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback function is called several times if tag is being written multiple pages.
|
||||
* DO NOT put heavy task here otherwise it will block tag write and cause timeout failure.
|
||||
**/
|
||||
void nfc_write_listener(void *arg, unsigned int page, unsigned int pgdat) {
|
||||
nfc_tag_content[page] = pgdat;
|
||||
nfc_tag_dirty[page] = 1;
|
||||
if (nfc_tid) {
|
||||
osSignalSet(nfc_tid, NFC_EV_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
int is_valid_nfc_uid() {
|
||||
int valid_content = 1;
|
||||
|
||||
unsigned char uid[7];
|
||||
unsigned char bcc[2];
|
||||
|
||||
uid[0] = (unsigned char)((nfc_tag_content[0] & 0x000000FF) >> 0);
|
||||
uid[1] = (unsigned char)((nfc_tag_content[0] & 0x0000FF00) >> 8);
|
||||
uid[2] = (unsigned char)((nfc_tag_content[0] & 0x00FF0000) >> 16);
|
||||
bcc[0] = (unsigned char)((nfc_tag_content[0] & 0xFF000000) >> 24);
|
||||
uid[3] = (unsigned char)((nfc_tag_content[1] & 0x000000FF) >> 0);
|
||||
uid[4] = (unsigned char)((nfc_tag_content[1] & 0x0000FF00) >> 8);
|
||||
uid[5] = (unsigned char)((nfc_tag_content[1] & 0x00FF0000) >> 16);
|
||||
uid[6] = (unsigned char)((nfc_tag_content[1] & 0xFF000000) >> 24);
|
||||
bcc[1] = (unsigned char)((nfc_tag_content[2] & 0x000000FF) >> 0);
|
||||
|
||||
// verify Block Check Character
|
||||
if (bcc[0] != (0x88 ^ uid[0] ^ uid[1] ^ uid[2])) {
|
||||
valid_content = 0;
|
||||
}
|
||||
if (bcc[1] != (uid[3] ^ uid[4] ^ uid[5] ^ uid[6])) {
|
||||
valid_content = 0;
|
||||
}
|
||||
|
||||
return valid_content;
|
||||
}
|
||||
|
||||
unsigned int generate_default_tag_content() {
|
||||
unsigned int page_size = 0;
|
||||
|
||||
memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int));
|
||||
|
||||
// calculate Block Check Character
|
||||
unsigned char bcc[2];
|
||||
bcc[0] = 0x88 ^ nfc_default_uid[0] ^ nfc_default_uid[1] ^ nfc_default_uid[2];
|
||||
bcc[1] = nfc_default_uid[3] ^ nfc_default_uid[4] ^ nfc_default_uid[5] ^ nfc_default_uid[6];
|
||||
|
||||
// generate header
|
||||
nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[0]) << 0 |
|
||||
((unsigned int)nfc_default_uid[1]) << 8 |
|
||||
((unsigned int)nfc_default_uid[2]) << 16 |
|
||||
((unsigned int) bcc[0]) << 24;
|
||||
nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[3]) << 0 |
|
||||
((unsigned int)nfc_default_uid[4]) << 8 |
|
||||
((unsigned int)nfc_default_uid[5]) << 16 |
|
||||
((unsigned int)nfc_default_uid[6]) << 24;
|
||||
nfc_tag_content[page_size++] = ((unsigned int) bcc[1]) << 0;
|
||||
nfc_tag_content[page_size++] = 0x001211E1;
|
||||
|
||||
// Init tag content as NDEF will-known text message "HELLO WORLD!" in little endian
|
||||
nfc_tag_content[page_size++] = 0x01d11303;
|
||||
nfc_tag_content[page_size++] = 0x6502540f;
|
||||
nfc_tag_content[page_size++] = 0x4c45486e;
|
||||
nfc_tag_content[page_size++] = 0x57204f4c;
|
||||
nfc_tag_content[page_size++] = 0x444c524f;
|
||||
nfc_tag_content[page_size++] = 0x0000fe21;
|
||||
|
||||
return page_size;
|
||||
}
|
||||
|
||||
void nfc_load_tag_content_from_flash() {
|
||||
int i, address, page_size;
|
||||
|
||||
memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int));
|
||||
memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM);
|
||||
|
||||
for (i = 0, address = FLASH_APP_NFC_BASE; i < NFC_MAX_PAGE_NUM; i++, address+=4) {
|
||||
flash_read_word(&flash_nfc, address, &nfc_tag_content[i]);
|
||||
}
|
||||
|
||||
if (!is_valid_nfc_uid() || NFC_RESTORE_DEFAULT) {
|
||||
DiagPrintf("Invalid tag content, restore to default value\r\n");
|
||||
page_size = generate_default_tag_content();
|
||||
|
||||
// update to flash
|
||||
flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE);
|
||||
for (i = 0, address = FLASH_APP_NFC_BASE; i < page_size; i++, address += 4) {
|
||||
flash_write_word(&flash_nfc, address, nfc_tag_content[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_store_tag_content_to_flash() {
|
||||
int i, address;
|
||||
int modified_page_count;
|
||||
|
||||
// dump the modified tag content
|
||||
modified_page_count = 4; // 4 for tag header
|
||||
for (i = 4; i < NFC_MAX_PAGE_NUM && nfc_tag_dirty[i]; i++) {
|
||||
modified_page_count++;
|
||||
DiagPrintf("page:%02d data:%08x\r\n", i, nfc_tag_content[i]);
|
||||
}
|
||||
|
||||
flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE);
|
||||
for (i = 0, address = FLASH_APP_NFC_BASE; i < modified_page_count; i++, address += 4) {
|
||||
flash_write_word(&flash_nfc, address, nfc_tag_content[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_task(void const *arg) {
|
||||
int i;
|
||||
osEvent evt;
|
||||
|
||||
nfc_load_tag_content_from_flash();
|
||||
|
||||
nfc_init(&nfctag, nfc_tag_content);
|
||||
nfc_event(&nfctag, nfc_event_listener, NULL, 0xFF);
|
||||
nfc_write(&nfctag, nfc_write_listener, NULL);
|
||||
|
||||
osSignalClear(nfc_tid, NFC_EV_WRITE);
|
||||
|
||||
while(1) {
|
||||
evt = osSignalWait (0, 0xFFFFFFFF); // wait for any signal with max timeout
|
||||
if (evt.status == osEventSignal && (evt.value.signals & NFC_EV_WRITE)) {
|
||||
osDelay(300);
|
||||
|
||||
nfc_store_tag_content_to_flash();
|
||||
|
||||
memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM);
|
||||
osSignalClear(nfc_tid, NFC_EV_WRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
osThreadDef(nfc_task, osPriorityRealtime, 1, 1024);
|
||||
nfc_tid = osThreadCreate (osThread (nfc_task), NULL);
|
||||
|
||||
DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_);
|
||||
|
||||
//3 3)Enable Schedule, Start Kernel
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
18
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/readme.txt
Executable file
18
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/readme.txt
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use deep sleep api.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
- PC_4 as input with internal pull-high, connect a push button to this pin and ground.
|
||||
- PC_5 as output, connect a LED to this pin and ground.
|
||||
|
||||
In this example, LED is turned on after device initialize.
|
||||
User push the button to turn off LED and trigger device enter deep sleep mode for 10s.
|
||||
If user press any key before sleep timeout, the system will resume.
|
||||
LED is turned on again after device initialize.
|
||||
|
||||
It can be easily measure power consumption in normal mode and deep sleep mode before/after push the putton.
|
||||
110
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/src/main.c
Executable file
110
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/src/main.c
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#include "sleep_ex_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN PC_5
|
||||
#define GPIO_IRQ_PIN PC_4
|
||||
|
||||
// deep sleep can only be waked up by GPIOB_1 and GTimer
|
||||
#define GPIO_WAKE_PIN PB_1
|
||||
|
||||
// NOTICE: The pull condition may differnet on your board
|
||||
PinName pull_down_list[] = {
|
||||
PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7,
|
||||
PB_0, PB_3, PB_4, PB_5, PB_6, PB_7,
|
||||
PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9,
|
||||
PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9,
|
||||
PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_A,
|
||||
PF_1, PF_2, PF_3, PF_4, PF_5
|
||||
};
|
||||
|
||||
// NOTICE: The pull condition may differnet on your board
|
||||
PinName pull_up_list[] = {
|
||||
PB_2,
|
||||
PF_0,
|
||||
PG_0, PG_1, PG_2, PG_3, PG_4, PG_5, PG_6, PG_7,
|
||||
PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7,
|
||||
PI_0, PI_1, PI_2, PI_3, PI_4, PI_5, PI_6, PI_7,
|
||||
PJ_0, PJ_1, PJ_2, PJ_3, PJ_4, PJ_5, PJ_6,
|
||||
PK_0, PK_1, PK_2, PK_3, PK_4, PK_5, PK_6
|
||||
};
|
||||
|
||||
void gpio_pull_control()
|
||||
{
|
||||
int i;
|
||||
gpio_t gpio_obj;
|
||||
|
||||
for (i=0; i < sizeof(pull_down_list) / sizeof(pull_down_list[0]); i++) {
|
||||
gpio_init(&gpio_obj, pull_down_list[i]);
|
||||
gpio_dir(&gpio_obj, PIN_INPUT);
|
||||
gpio_mode(&gpio_obj, PullDown);
|
||||
}
|
||||
|
||||
for (i=0; i < sizeof(pull_up_list) / sizeof(pull_up_list[0]); i++) {
|
||||
gpio_init(&gpio_obj, pull_up_list[i]);
|
||||
gpio_dir(&gpio_obj, PIN_INPUT);
|
||||
gpio_mode(&gpio_obj, PullUp);
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
gpio_t *gpio_led;
|
||||
gpio_led = (gpio_t *)id;
|
||||
|
||||
printf("Enter deep sleep...Wait 10s or give rising edge at PB_1 to wakeup system.\r\n\r\n");
|
||||
|
||||
// turn off led
|
||||
gpio_write(gpio_led, 0);
|
||||
|
||||
// turn off log uart
|
||||
sys_log_uart_off();
|
||||
|
||||
// initialize wakeup pin at PB_1
|
||||
gpio_t gpio_wake;
|
||||
gpio_init(&gpio_wake, GPIO_WAKE_PIN);
|
||||
gpio_dir(&gpio_wake, PIN_INPUT);
|
||||
gpio_mode(&gpio_wake, PullDown);
|
||||
|
||||
// Please note that the pull control is different in different board
|
||||
// This example is a sample code for RTL Ameba Dev Board
|
||||
gpio_pull_control();
|
||||
|
||||
// enter deep sleep
|
||||
deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO | DSLEEP_WAKEUP_BY_TIMER, 10000);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gpio_t gpio_led;
|
||||
gpio_irq_t gpio_btn;
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led));
|
||||
gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_btn);
|
||||
|
||||
// led on means system is in run mode
|
||||
gpio_write(&gpio_led, 1);
|
||||
printf("\r\nPush button at PC_4 to enter deep sleep\r\n");
|
||||
|
||||
while(1);
|
||||
}
|
||||
18
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/readme.txt
Executable file
18
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/readme.txt
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use deep standby api.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
Pin name PA_5 and PC_5 map to GPIOA_5 and GPIOC_5:
|
||||
- PA_5 as input, connect a push button to this pin and 3v3.
|
||||
- PC_5 as output, connect a LED to this pin and ground.
|
||||
|
||||
In this example, LED is turned on after device initialize.
|
||||
User push the button to turn off LED and trigger device enter deep standby mode for 10s.
|
||||
If user press button before sleep timeout, the system will resume.
|
||||
LED is turned on again after device initialize.
|
||||
|
||||
It can be easily measure power consumption in normal mode and deep standby mode before/after push the putton.
|
||||
104
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/src/main.c
Executable file
104
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/src/main.c
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "sleep_ex_api.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN PC_5
|
||||
#define GPIO_PUSHBT_PIN PA_5
|
||||
|
||||
// NOTICE: The pull condition may differnet on your board
|
||||
PinName pull_down_list[] = {
|
||||
PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7,
|
||||
PB_0, PB_1, PB_3, PB_4, PB_5, PB_6, PB_7,
|
||||
PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9,
|
||||
PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9,
|
||||
PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_A,
|
||||
PF_1, PF_2, PF_3, PF_4, PF_5
|
||||
};
|
||||
|
||||
// NOTICE: The pull condition may differnet on your board
|
||||
PinName pull_up_list[] = {
|
||||
PB_2,
|
||||
PF_0,
|
||||
PG_0, PG_1, PG_2, PG_3, PG_4, PG_5, PG_6, PG_7,
|
||||
PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7,
|
||||
PI_0, PI_1, PI_2, PI_3, PI_4, PI_5, PI_6, PI_7,
|
||||
PJ_0, PJ_1, PJ_2, PJ_3, PJ_4, PJ_5, PJ_6,
|
||||
PK_0, PK_1, PK_2, PK_3, PK_4, PK_5, PK_6
|
||||
};
|
||||
|
||||
void gpio_pull_control()
|
||||
{
|
||||
int i;
|
||||
gpio_t gpio_obj;
|
||||
|
||||
for (i=0; i < sizeof(pull_down_list) / sizeof(pull_down_list[0]); i++) {
|
||||
gpio_init(&gpio_obj, pull_down_list[i]);
|
||||
gpio_dir(&gpio_obj, PIN_INPUT);
|
||||
gpio_mode(&gpio_obj, PullDown);
|
||||
}
|
||||
|
||||
for (i=0; i < sizeof(pull_up_list) / sizeof(pull_up_list[0]); i++) {
|
||||
gpio_init(&gpio_obj, pull_up_list[i]);
|
||||
gpio_dir(&gpio_obj, PIN_INPUT);
|
||||
gpio_mode(&gpio_obj, PullUp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
gpio_t gpio_led, gpio_btn;
|
||||
int old_btn_state, new_btn_state;
|
||||
|
||||
DBG_INFO_MSG_OFF(_DBG_GPIO_);
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
// Initial Push Button pin
|
||||
gpio_init(&gpio_btn, GPIO_PUSHBT_PIN);
|
||||
gpio_dir(&gpio_btn, PIN_INPUT); // Direction: Input
|
||||
gpio_mode(&gpio_btn, PullDown);
|
||||
|
||||
old_btn_state = new_btn_state = 0;
|
||||
gpio_write(&gpio_led, 1);
|
||||
|
||||
DiagPrintf("Push button to sleep...\r\n");
|
||||
while(1){
|
||||
new_btn_state = gpio_read(&gpio_btn);
|
||||
|
||||
if (old_btn_state == 1 && new_btn_state == 0) {
|
||||
gpio_write(&gpio_led, 0);
|
||||
|
||||
// Please note that the pull control is different in different board
|
||||
// This example is a sample code for RTL Ameba Dev Board
|
||||
gpio_pull_control();
|
||||
|
||||
DiagPrintf("Sleep 8s... (Or wakeup by pushing button)\r\n");
|
||||
standby_wakeup_event_add(STANDBY_WAKEUP_BY_STIMER, 8000, 0);
|
||||
standby_wakeup_event_add(STANDBY_WAKEUP_BY_PA5, 0, 1);
|
||||
deepstandby_ex();
|
||||
|
||||
DiagPrintf("This line should not be printed\r\n");
|
||||
}
|
||||
old_btn_state = new_btn_state;
|
||||
}
|
||||
}
|
||||
|
||||
18
project/realtek_ameba1_va0_example/example_sources/pm_sleep/readme.txt
Executable file
18
project/realtek_ameba1_va0_example/example_sources/pm_sleep/readme.txt
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use sleep api.
|
||||
|
||||
Requirement Components:
|
||||
a LED
|
||||
a push button
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
- PC_4 as input with internal pull-high, connect a push button to this pin and ground.
|
||||
- PC_5 as output, connect a LED to this pin and ground.
|
||||
|
||||
In this example, LED is turned on after device initialize.
|
||||
User push the button to turn off LED and trigger device enter sleep mode for 10s.
|
||||
If user push button before sleep timeout, the system will resume.
|
||||
LED is turned on again after system resume without restart PC.
|
||||
|
||||
It can be easily measure power consumption in normal mode and sleep mode before/after push the putton.
|
||||
81
project/realtek_ameba1_va0_example/example_sources/pm_sleep/src/main.c
Executable file
81
project/realtek_ameba1_va0_example/example_sources/pm_sleep/src/main.c
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#include "sleep_ex_api.h"
|
||||
#include "sys_api.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_LED_PIN PC_5
|
||||
#define GPIO_IRQ_PIN PC_4
|
||||
|
||||
int led_ctrl = 0;
|
||||
gpio_t gpio_led;
|
||||
|
||||
int put_to_sleep = 0;
|
||||
|
||||
void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
gpio_t *gpio_led;
|
||||
|
||||
gpio_led = (gpio_t *)id;
|
||||
|
||||
if (led_ctrl == 1) {
|
||||
led_ctrl = 0;
|
||||
gpio_write(gpio_led, led_ctrl);
|
||||
put_to_sleep = 1;
|
||||
} else {
|
||||
led_ctrl = 1;
|
||||
gpio_write(gpio_led, led_ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
gpio_irq_t gpio_btn;
|
||||
|
||||
DBG_INFO_MSG_OFF(_DBG_GPIO_);
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_led, GPIO_LED_PIN);
|
||||
gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_led, PullNone); // No pull
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led));
|
||||
gpio_irq_set(&gpio_btn, IRQ_FALL, 1);
|
||||
gpio_irq_enable(&gpio_btn);
|
||||
|
||||
led_ctrl = 1;
|
||||
gpio_write(&gpio_led, led_ctrl);
|
||||
DBG_8195A("Push button to enter sleep\r\n");
|
||||
|
||||
put_to_sleep = 0;
|
||||
while(1) {
|
||||
if (put_to_sleep) {
|
||||
DBG_8195A("Sleep 8s or push button to resume system...\r\n");
|
||||
sys_log_uart_off();
|
||||
sleep_ex(SLP_GPIO | SLEEP_WAKEUP_BY_STIMER, 8000); // sleep_ex can't be put in irq handler
|
||||
sys_log_uart_on();
|
||||
DBG_8195A("System resume\r\n");
|
||||
|
||||
put_to_sleep = 0;
|
||||
led_ctrl = 1;
|
||||
gpio_write(&gpio_led, led_ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
project/realtek_ameba1_va0_example/example_sources/pm_tickless/readme.txt
Executable file
31
project/realtek_ameba1_va0_example/example_sources/pm_tickless/readme.txt
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use freertos tickless with uart interruptable interface
|
||||
|
||||
Requirement Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_0 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_4 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
We also need connect GPIOC_1 as gpio interrupt which parallel with log uart rx pin.
|
||||
|
||||
In this example, freertos will enter/leave tickless automatically.
|
||||
User can type continuous "Enter" in uart or log uart to wake system if system is in tickless.
|
||||
System is keep awake until user type a command via uart.
|
||||
|
||||
There are some features in this example:
|
||||
(1) We replace tickless' sleep function with system sleep api which save more power.
|
||||
(2) Freertos enter tickless if the wakelock bit map is 0.
|
||||
It means there is no function require system keep awake.
|
||||
By default there is WAKELOCK_OS keep system awake.
|
||||
So we need release this WAKELOCK_OS enable tickless mode.
|
||||
(3) We configure uart rx as gpio interrupt mode. This make uart can wake system.
|
||||
|
||||
NOTICE: If you don't want loss any data from treating UART signal as GPIO interrupt,
|
||||
you can set FREERTOS_PMU_TICKLESS_PLL_RESERVED to 1 in "platform_opt.h".
|
||||
It will reserved PLL clock in tickless and UART can receive the whole data.
|
||||
But it also cost more power consumption.
|
||||
168
project/realtek_ameba1_va0_example/example_sources/pm_tickless/src/main.c
Executable file
168
project/realtek_ameba1_va0_example/example_sources/pm_tickless/src/main.c
Executable file
|
|
@ -0,0 +1,168 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include <example_entry.h>
|
||||
|
||||
#include "freertos_pmu.h"
|
||||
#include "gpio_irq_api.h"
|
||||
#include "serial_api.h"
|
||||
|
||||
// select uart tx/rx pin with gpio interrupt function
|
||||
#define UART_TX PA_4
|
||||
#define UART_RX PA_0
|
||||
|
||||
#define LOGUART_RX_WAKE PC_1
|
||||
|
||||
#define WAKELOCK_EXAMPLE WAKELOCK_USER_BASE
|
||||
|
||||
serial_t mysobj;
|
||||
volatile char rc = 0;
|
||||
|
||||
extern void wlan_netowrk(void);
|
||||
extern void console_init(void);
|
||||
|
||||
char cmdbuf[128];
|
||||
int cmdbuf_index = 0;
|
||||
void uart_irq_callback(uint32_t id, SerialIrq event)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
|
||||
if(event == RxIrq) {
|
||||
acquire_wakelock(WAKELOCK_EXAMPLE);
|
||||
|
||||
rc = serial_getc(sobj);
|
||||
|
||||
if (rc == '\r' || rc == '\n') {
|
||||
serial_putc(sobj, '\r');
|
||||
serial_putc(sobj, '\n');
|
||||
serial_putc(sobj, '#');
|
||||
serial_putc(sobj, ' ');
|
||||
|
||||
if (cmdbuf_index != 0) {
|
||||
|
||||
/* NOTICE: If you don't want loss any data from treating UART signal as GPIO interrupt,
|
||||
* you can set FREERTOS_PMU_TICKLESS_PLL_RESERVED to 1 in "platform_opt.h".
|
||||
* It will reserved PLL clock in tickless and UART can receive the whole data.
|
||||
* But it also cost more power consumption.
|
||||
**/
|
||||
|
||||
// process command
|
||||
printf("cmd(%d): %s\r\n", cmdbuf_index, cmdbuf);
|
||||
|
||||
// release wakelock and reset buf
|
||||
cmdbuf_index = 0;
|
||||
release_wakelock(WAKELOCK_EXAMPLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(rc == '\r' || rc == '\n' )) {
|
||||
// receive command
|
||||
serial_putc(sobj, rc);
|
||||
cmdbuf[cmdbuf_index] = rc;
|
||||
cmdbuf_index++;
|
||||
cmdbuf[cmdbuf_index] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_uart_rx_irq_callback(uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
acquire_wakelock(WAKELOCK_EXAMPLE);
|
||||
}
|
||||
|
||||
void pre_sleep_process_callback(unsigned int expected_idle_time)
|
||||
{
|
||||
// For peripherals that need turned off before sleep, call disable or deinit peripheral here
|
||||
}
|
||||
|
||||
void post_sleep_process_callback(unsigned int expected_idle_time)
|
||||
{
|
||||
// For peripherals that are turned off before sleep, call enable or init peripheral here
|
||||
}
|
||||
|
||||
void config_uart()
|
||||
{
|
||||
// setup uart
|
||||
serial_init(&mysobj, UART_TX, UART_RX);
|
||||
serial_baud(&mysobj, 38400);
|
||||
serial_format(&mysobj, 8, ParityNone, 1);
|
||||
|
||||
serial_irq_handler(&mysobj, uart_irq_callback, (uint32_t)&mysobj);
|
||||
serial_irq_set(&mysobj, RxIrq, 1);
|
||||
serial_irq_set(&mysobj, TxIrq, 1);
|
||||
|
||||
// config uart rx as gpio wakeup pin
|
||||
gpio_irq_t gpio_rx_wake;
|
||||
gpio_irq_init(&gpio_rx_wake, UART_RX, gpio_uart_rx_irq_callback, NULL);
|
||||
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_rx_wake);
|
||||
}
|
||||
|
||||
void gpio_loguart_rx_irq_callback (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
/* WAKELOCK_LOGUART is also handled in log service.
|
||||
* It is release after a complete command is sent.
|
||||
**/
|
||||
acquire_wakelock(WAKELOCK_LOGUART);
|
||||
}
|
||||
|
||||
void config_loguart()
|
||||
{
|
||||
/* Log uart RX pin doesn't support gpio interrupt.
|
||||
* To make log uart wake system, we can parallel log uart RX with another gpio interrupt pin.
|
||||
*/
|
||||
gpio_irq_t gpio_rx_wake;
|
||||
gpio_irq_init(&gpio_rx_wake, LOGUART_RX_WAKE, gpio_loguart_rx_irq_callback, NULL);
|
||||
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_rx_wake);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
if ( rtl_cryptoEngine_init() != 0 ) {
|
||||
DiagPrintf("crypto engine init failed\r\n");
|
||||
}
|
||||
|
||||
/* Initialize log uart and at command service */
|
||||
console_init();
|
||||
|
||||
/* pre-processor of application example */
|
||||
pre_example_entry();
|
||||
|
||||
/* wlan intialization */
|
||||
#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK)
|
||||
wlan_network();
|
||||
#endif
|
||||
|
||||
// setup uart with capability of wakeup system
|
||||
config_uart();
|
||||
|
||||
// setup log uart with capability of wakeup system
|
||||
config_loguart();
|
||||
|
||||
// By default tickless is disabled because WAKELOCK_OS is locked.
|
||||
// Release this wakelock to enable tickless
|
||||
release_wakelock(WAKELOCK_OS);
|
||||
|
||||
// Register pre/post sleep callback. They are called when system automatically enter/leave sleep.
|
||||
register_pre_sleep_callback(pre_sleep_process_callback);
|
||||
register_post_sleep_callback(post_sleep_process_callback);
|
||||
|
||||
/* Execute application example */
|
||||
example_entry();
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
}
|
||||
10
project/realtek_ameba1_va0_example/example_sources/pwm-buzzer/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/pwm-buzzer/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use pwm buzzer on extend board
|
||||
|
||||
Requirement Components:
|
||||
extend board, buzzer
|
||||
|
||||
Connect extend board to 2v0 dap board, and connect buzzer on the extend board's buzzer pin, then the buzzer would play sound from Do to higher Do.
|
||||
|
||||
|
||||
63
project/realtek_ameba1_va0_example/example_sources/pwm-buzzer/src/main.c
Executable file
63
project/realtek_ameba1_va0_example/example_sources/pwm-buzzer/src/main.c
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "pwmout_api.h" // mbed
|
||||
#include "main.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#define PWM_1 PC_0
|
||||
#define PWM_2 PC_1
|
||||
#define PWM_3 PC_2
|
||||
#define PWM_4 PC_3
|
||||
|
||||
|
||||
|
||||
pwmout_t pwm_led[4];
|
||||
PinName pwm_led_pin[4] = {PWM_1, PWM_2, PWM_3, PWM_4};
|
||||
float period[8] = {1.0/523, 1.0/587, 1.0/659, 1.0/698, 1.0/784, 1.0/880, 1.0/988, 1.0/1047};
|
||||
|
||||
extern void RtlMsleepOS(u32 ms);
|
||||
|
||||
void pwm_delay(void)
|
||||
{
|
||||
for(int i=0;i<1000000;i++)
|
||||
asm(" nop");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
//int main_app(IN u16 argc, IN u8 *argv[])
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
pwmout_init(&pwm_led[3], pwm_led_pin[3]);
|
||||
|
||||
|
||||
|
||||
while (1) {
|
||||
|
||||
for(i=0; i<8; i++){
|
||||
pwmout_period(&pwm_led[3], period[i]);
|
||||
pwmout_pulsewidth(&pwm_led[3], period[i]/2);
|
||||
Mdelay(1000);
|
||||
}
|
||||
|
||||
|
||||
// wait_ms(20);
|
||||
// RtlMsleepOS(25);
|
||||
pwm_delay();
|
||||
}
|
||||
}
|
||||
|
||||
13
project/realtek_ameba1_va0_example/example_sources/pwm/readme.txt
Executable file
13
project/realtek_ameba1_va0_example/example_sources/pwm/readme.txt
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use pwm
|
||||
|
||||
Requirement Components:
|
||||
1~4 LED
|
||||
|
||||
Connect LED to below PWM pins and ground, then the LED would gradually become brighter and then darker with different speed.
|
||||
- connect a LED to PC_0 and ground
|
||||
- connect a LED to PC_1 and ground
|
||||
- connect a LED to PC_2 and ground
|
||||
- connect a LED to PC_3 and ground
|
||||
|
||||
94
project/realtek_ameba1_va0_example/example_sources/pwm/src/main.c
Executable file
94
project/realtek_ameba1_va0_example/example_sources/pwm/src/main.c
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "pwmout_api.h" // mbed
|
||||
#include "main.h"
|
||||
|
||||
#define PWM_1 PC_0
|
||||
#define PWM_2 PC_1
|
||||
#define PWM_3 PC_2
|
||||
#define PWM_4 PC_3
|
||||
#define PWM_PERIOD 20000
|
||||
#define USE_FLOAT 0
|
||||
|
||||
#if USE_FLOAT
|
||||
#define PWM_STEP (1.0/20.0)
|
||||
float pwms[4]={0.0, 0.25, 0.5, 0.75};
|
||||
float steps[4]={PWM_STEP, PWM_STEP, PWM_STEP, PWM_STEP};
|
||||
#else
|
||||
#define PWM_STEP (PWM_PERIOD/20)
|
||||
int pwms[4]={0, PWM_PERIOD/4, PWM_PERIOD/2, PWM_PERIOD/4*3};
|
||||
int steps[4]={PWM_STEP,PWM_STEP,PWM_STEP,PWM_STEP};
|
||||
#endif
|
||||
|
||||
pwmout_t pwm_led[4];
|
||||
PinName pwm_led_pin[4] = {PWM_1, PWM_2, PWM_3, PWM_4};
|
||||
|
||||
extern void RtlMsleepOS(u32 ms);
|
||||
|
||||
void pwm_delay(void)
|
||||
{
|
||||
for(int i=0;i<1000000;i++)
|
||||
asm(" nop");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
//int main_app(IN u16 argc, IN u8 *argv[])
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
pwmout_init(&pwm_led[i], pwm_led_pin[i]);
|
||||
pwmout_period_us(&pwm_led[i], PWM_PERIOD);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
#if USE_FLOAT
|
||||
for (i=0; i<4; i++) {
|
||||
pwmout_write(&pwm_led[i], pwms[i]);
|
||||
|
||||
pwms[i] += steps[i];
|
||||
if (pwms[i] >= 1.0) {
|
||||
steps[i] = -PWM_STEP;
|
||||
pwms[i] = 1.0;
|
||||
}
|
||||
|
||||
if (pwms[i] <= 0.0) {
|
||||
steps[i] = PWM_STEP;
|
||||
pwms[i] = 0.0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i=0; i<4; i++) {
|
||||
pwmout_pulsewidth_us(&pwm_led[i], pwms[i]);
|
||||
|
||||
pwms[i] += steps[i];
|
||||
if (pwms[i] >= PWM_PERIOD) {
|
||||
steps[i] = -PWM_STEP;
|
||||
pwms[i] = PWM_PERIOD;
|
||||
}
|
||||
|
||||
if (pwms[i] <= 0) {
|
||||
steps[i] = PWM_STEP;
|
||||
pwms[i] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// wait_ms(20);
|
||||
// RtlMsleepOS(25);
|
||||
pwm_delay();
|
||||
}
|
||||
}
|
||||
|
||||
7
project/realtek_ameba1_va0_example/example_sources/rtc/readme.txt
Executable file
7
project/realtek_ameba1_va0_example/example_sources/rtc/readme.txt
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use the RTC API. The RTC function is implemented by a G-Timer.
|
||||
|
||||
Behavior:
|
||||
This example will print out the time information every secand.
|
||||
|
||||
34
project/realtek_ameba1_va0_example/example_sources/rtc/src/main.c
Executable file
34
project/realtek_ameba1_va0_example/example_sources/rtc/src/main.c
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
time_t seconds;
|
||||
struct tm *timeinfo;
|
||||
|
||||
rtc_init();
|
||||
rtc_write(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37
|
||||
|
||||
while(1) {
|
||||
seconds = rtc_read();
|
||||
timeinfo = localtime(&seconds);
|
||||
|
||||
DBG_8195A("Time as seconds since January 1, 1970 = %d\n", seconds);
|
||||
|
||||
DBG_8195A("Time as a basic string = %s", ctime(&seconds));
|
||||
|
||||
DBG_8195A("Time as a custom formatted string = %d-%d-%d %d:%d:%d ",
|
||||
timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour,
|
||||
timeinfo->tm_min,timeinfo->tm_sec);
|
||||
|
||||
wait(1);
|
||||
}
|
||||
}
|
||||
|
||||
23
project/realtek_ameba1_va0_example/example_sources/spi/readme.txt
Executable file
23
project/realtek_ameba1_va0_example/example_sources/spi/readme.txt
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use SPI read/write by mbed api.
|
||||
|
||||
|
||||
The SPI Interface provides a "Serial Peripheral Interface" Master.
|
||||
|
||||
This interface can be used for communication with SPI slave devices,
|
||||
such as FLASH memory, LCD screens and other modules or integrated circuits.
|
||||
|
||||
In this example, it use 2 sets of SPI. One is master, the other is slave.
|
||||
By default it use SPI0 as slave, and use SPI2 as master.
|
||||
So we connect them as below:
|
||||
Connect SPI0_MOSI (PC_2) to SPI2_MOSI (PA_1)
|
||||
Connect SPI0_MISO (PC_3) to SPI2_MISO (PA_0)
|
||||
Connect SPI0_SCLK (PC_1) to SPI2_SCLK (PA_2)
|
||||
Connect SPI0_CS (PC_0) to SPI2_CS (PA_4)
|
||||
|
||||
Because some GPIOA are used as SDIO purpose which has higher priority.
|
||||
So we need pull high PA_7 when device boot up.
|
||||
Connect PA_7 to 3V3
|
||||
|
||||
After boot up, the master will send data to slave and shows result on LOG_OUT.
|
||||
127
project/realtek_ameba1_va0_example/example_sources/spi/src/main.c
Executable file
127
project/realtek_ameba1_va0_example/example_sources/spi/src/main.c
Executable file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2014 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include "spi_api.h"
|
||||
|
||||
#define FakeMbedAPI 1
|
||||
|
||||
// SPI0 (S0)
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0
|
||||
|
||||
// SPI1 (S1)
|
||||
#define SPI1_MOSI PB_6
|
||||
#define SPI1_MISO PB_7
|
||||
#define SPI1_SCLK PB_5
|
||||
#define SPI1_CS PB_4
|
||||
|
||||
#if 1
|
||||
// SPI2 (S2) for DEV 3V0
|
||||
// Please note that PA_7 need pull high before using GPIOA group
|
||||
#define SPI2_MOSI PA_1
|
||||
#define SPI2_MISO PA_0
|
||||
#define SPI2_SCLK PA_2
|
||||
#define SPI2_CS PA_4
|
||||
#else
|
||||
// SPI2 (S2)
|
||||
#define SPI2_MOSI PD_2
|
||||
#define SPI2_MISO PD_3
|
||||
#define SPI2_SCLK PD_1
|
||||
#define SPI2_CS PD_0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
spi_t spi_master;
|
||||
spi_t spi_slave;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#if FakeMbedAPI
|
||||
|
||||
/* SPI0 is as Slave */
|
||||
//SPI0_IS_AS_SLAVE = 1;
|
||||
|
||||
spi_init(&spi_master, SPI2_MOSI, SPI2_MISO, SPI2_SCLK, SPI2_CS);
|
||||
spi_format(&spi_master, 8, 0, 0);
|
||||
spi_frequency(&spi_master, 200000);
|
||||
spi_init(&spi_slave, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
spi_format(&spi_slave, 8, 0, 1);
|
||||
|
||||
int TestingTimes = 10;
|
||||
int Counter = 0;
|
||||
int TestData = 0;
|
||||
int ReadData = 0;
|
||||
|
||||
int result = 1;
|
||||
|
||||
/**
|
||||
* Master read/write, Slave read/write
|
||||
*/
|
||||
DBG_SSI_INFO("--------------------------------------------------------\n");
|
||||
for(Counter = 0, TestData=0x01; Counter < TestingTimes; Counter++)
|
||||
{
|
||||
ReadData = spi_master_write(&spi_master, TestData);
|
||||
DBG_SSI_INFO("Master write: %02X, read: %02X\n", TestData, ReadData);
|
||||
if (TestData - 1 != ReadData) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
TestData++;
|
||||
|
||||
spi_slave_write(&spi_slave, TestData);
|
||||
ReadData = spi_slave_read(&spi_slave);
|
||||
DBG_SSI_INFO(ANSI_COLOR_CYAN"Slave write: %02X, read: %02X\n"ANSI_COLOR_RESET, TestData, ReadData);
|
||||
if (TestData - 1 != ReadData) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
TestData++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Master write, Slave read
|
||||
*/
|
||||
DBG_SSI_INFO("--------------------------------------------------------\n");
|
||||
for(Counter = 0, TestData=0xFF; Counter < TestingTimes; Counter++)
|
||||
{
|
||||
spi_master_write(&spi_master, TestData);
|
||||
ReadData = spi_slave_read(&spi_slave);
|
||||
DBG_SSI_INFO("Master write: %02X\n", TestData);
|
||||
DBG_SSI_INFO(ANSI_COLOR_CYAN"Slave read : %02X\n"ANSI_COLOR_RESET, ReadData);
|
||||
if (TestData != ReadData) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
TestData--;
|
||||
}
|
||||
|
||||
spi_free(&spi_master);
|
||||
spi_free(&spi_slave);
|
||||
|
||||
DBG_SSI_INFO("SPI Demo finished.\n");
|
||||
|
||||
printf("\r\nResult is %s\r\n", (result) ? "success" : "fail");
|
||||
|
||||
for(;;);
|
||||
|
||||
#else // mbed SPI API emulation
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
19
project/realtek_ameba1_va0_example/example_sources/spi_pl7223/readme.txt
Executable file
19
project/realtek_ameba1_va0_example/example_sources/spi_pl7223/readme.txt
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to get data from pl7223 by SPI conneciton
|
||||
|
||||
The SPI Interface provides a "Serial Peripheral Interface" Master.
|
||||
|
||||
Hardware connection:
|
||||
Connect SPI0_MOSI (PC_2) to PL7223 MOSI
|
||||
Connect SPI0_MISO (PC_3) to PL7223 MISO
|
||||
Connect SPI0_SCLK (PC_1) to PL7223 SCLK
|
||||
Connect GPIOB_5 (PB_5) to PL7223 CS
|
||||
Connect GPIOB_4 (PB_4) to PL7223 RESET
|
||||
Connect GROUND together
|
||||
|
||||
Connect to LOG UART with configuration 38400 8bits, 1 stopbit, no parity
|
||||
|
||||
|
||||
After boot up, the ameba will reset pl7223 into MCU mode and get data from pl7223.
|
||||
After Gatherin and calculating, program will show information to UART.
|
||||
298
project/realtek_ameba1_va0_example/example_sources/spi_pl7223/src/main.c
Executable file
298
project/realtek_ameba1_va0_example/example_sources/spi_pl7223/src/main.c
Executable file
|
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "device.h"
|
||||
#include "main.h"
|
||||
#include "spi_api.h"
|
||||
#include "gpio_api.h"
|
||||
|
||||
// SPI0
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0
|
||||
|
||||
#define GPIO_RESET PB_4
|
||||
#define GPIO_CS PB_5
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
#define READ_PL7223 0x4000
|
||||
#define WRITE_PL7223 0x8000
|
||||
#define DSPSTATUS_PL7223 0xF000
|
||||
#define DUM_PL7223 0x00 //Dummy Data
|
||||
|
||||
unsigned char SPDAT; // simulate example code
|
||||
unsigned char DSP_STATUS=0;
|
||||
unsigned char Read_Data_PL7223[146]; // Read_Data; 256Bytes=1Page
|
||||
unsigned char Write_Data_PL7223[146]; // Write_Data; 256Bytes=1Page
|
||||
unsigned char Cmd_RD=0;
|
||||
|
||||
|
||||
long EE_Temp = 0;
|
||||
float VA_rms=0;
|
||||
float IA_rms=0;
|
||||
float PA=0;
|
||||
float SA=0;
|
||||
float QA=0;
|
||||
float PF_A=0;
|
||||
float Theta_A=0;
|
||||
float Frequency=0;
|
||||
int Sample_cnt0=0;
|
||||
int ZCC_cnt=0;
|
||||
int ZCC_Start=0;
|
||||
int ZCC_Stop=0;
|
||||
|
||||
void Initial_SPI_PL7223(void);
|
||||
void SPI_PL7223_SEND(unsigned char);
|
||||
void SPI__PL7223_Read_Status(void);
|
||||
void SPI_PL7223_DELY(int);
|
||||
void SPI_PL7223_Reset(void);
|
||||
void SPI_PL7223_Read(unsigned char*, unsigned int, unsigned int);
|
||||
void SPI_PL7223_Write(unsigned char*, unsigned int, unsigned int);
|
||||
void SPI_PL7223_Masurement(void);
|
||||
void SPI_PL7223_RelayControl(int);
|
||||
|
||||
static spi_t spi0_master;
|
||||
static gpio_t gpio_reset;
|
||||
static gpio_t gpio_cs;
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
|
||||
gpio_init(&gpio_reset, GPIO_RESET);
|
||||
gpio_mode(&gpio_reset, PullUp);
|
||||
gpio_dir(&gpio_reset, PIN_OUTPUT);
|
||||
|
||||
gpio_init(&gpio_cs, GPIO_CS);
|
||||
gpio_mode(&gpio_cs, PullUp);
|
||||
gpio_dir(&gpio_cs, PIN_OUTPUT);
|
||||
|
||||
spi_init(&spi0_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
spi_format(&spi0_master, 8, 3, 0);
|
||||
spi_frequency(&spi0_master, 800000);
|
||||
|
||||
do
|
||||
{
|
||||
SPI_PL7223_Reset();
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[0],0x3860,1);//DSP version :20130322 ver02, 0x3860=0x04
|
||||
//DSP version :20141009 ver01, 0x3860=0x03
|
||||
}while( ((Read_Data_PL7223[0]) != 0x04) && ((Read_Data_PL7223[0]) != 0x03) );
|
||||
|
||||
SPI_PL7223_DELY(120000);
|
||||
SPI_PL7223_RelayControl(0); // OFF
|
||||
SPI_PL7223_DELY(120000);
|
||||
|
||||
do{
|
||||
// As below is read DSP buffer process every time (144 byte)
|
||||
SPI__PL7223_Read_Status();
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0
|
||||
SPI_PL7223_Masurement();
|
||||
|
||||
SPI_PL7223_DELY(600000);
|
||||
SPI_PL7223_RelayControl(1); // ON
|
||||
SPI_PL7223_DELY(120000);
|
||||
|
||||
SPI__PL7223_Read_Status();
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0
|
||||
SPI_PL7223_Masurement();
|
||||
|
||||
SPI_PL7223_DELY(600000);
|
||||
SPI_PL7223_RelayControl(0); // OFF
|
||||
SPI_PL7223_DELY(120000);
|
||||
}while(1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_RelayControl(int sw)
|
||||
{
|
||||
#define RELAY_MASK (1<<5)
|
||||
SPI_PL7223_Read(&Read_Data_PL7223[0],0x380F,1);
|
||||
if(!sw)
|
||||
Read_Data_PL7223[0] &= (~RELAY_MASK);
|
||||
else
|
||||
Read_Data_PL7223[0] |= RELAY_MASK;
|
||||
SPI_PL7223_Write(&Read_Data_PL7223[0],0x380F,1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_Reset(void)
|
||||
{
|
||||
gpio_write(&gpio_cs, 0);
|
||||
SPI_PL7223_DELY(500); //need delay 10ms
|
||||
gpio_write(&gpio_reset, 1);
|
||||
SPI_PL7223_DELY(500); //need delay 10ms
|
||||
gpio_write(&gpio_reset, 0);
|
||||
SPI_PL7223_DELY(500); //need delay 10ms
|
||||
gpio_write(&gpio_reset, 1);
|
||||
SPI_PL7223_DELY(500); //need delay 10ms
|
||||
gpio_write(&gpio_cs, 1);
|
||||
SPI_PL7223_DELY(300);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI__PL7223_Read_Status(void)
|
||||
{
|
||||
gpio_write(&gpio_cs, 0);
|
||||
SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223 >> 8)& 0xFF); // RDSR command
|
||||
SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command
|
||||
|
||||
//check DSP flag state (byte)
|
||||
do
|
||||
{
|
||||
SPI_PL7223_SEND(DUM_PL7223);
|
||||
DSP_STATUS=SPDAT;
|
||||
}while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready
|
||||
gpio_write(&gpio_cs, 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_Write(unsigned char* buf, unsigned int addr, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
gpio_write(&gpio_cs, 0);
|
||||
addr |= WRITE_PL7223; // Write command
|
||||
SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address
|
||||
SPI_PL7223_SEND((unsigned char)(addr & 0xFF));// Write low byte address
|
||||
for (i = 0; i < len ; i++){
|
||||
SPI_PL7223_SEND(buf[i]);
|
||||
}
|
||||
gpio_write(&gpio_cs, 1);
|
||||
SPI_PL7223_DELY(3); // for CS:Hi to Low need 100nsec, Delay-Time 27usec
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
|
||||
void SPI_PL7223_Read(unsigned char* buf, unsigned int addr, unsigned int len)
|
||||
{
|
||||
static unsigned int i;
|
||||
|
||||
gpio_write(&gpio_cs, 0);
|
||||
|
||||
addr |= READ_PL7223; // Read command
|
||||
SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address
|
||||
SPI_PL7223_SEND((unsigned char)(addr & 0x00FF)); // Write low byte address
|
||||
|
||||
for(i=0;i<len;i++){ // Read 256 Bytes/Page to Flash Memory
|
||||
SPI_PL7223_SEND(DUM_PL7223); // Send Dummy Data to Read righ Data
|
||||
buf[i] = SPDAT; // Read SPIDAT and clear TX complete flag
|
||||
}
|
||||
|
||||
gpio_write(&gpio_cs, 1);
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_Read_Status(void)
|
||||
{
|
||||
|
||||
gpio_write(&gpio_cs, 0);
|
||||
SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223 >> 8)& 0xFF); // RDSR command
|
||||
SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command
|
||||
|
||||
do
|
||||
{
|
||||
SPI_PL7223_SEND(DUM_PL7223);
|
||||
DSP_STATUS=SPDAT;
|
||||
}while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready
|
||||
|
||||
gpio_write(&gpio_cs, 1);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
|
||||
void SPI_PL7223_Masurement(void)
|
||||
{
|
||||
|
||||
//Vrms address : 0x3002~0x3003
|
||||
// VA_rms = (Read_Data_PL7223[3]*256+Read_Data_PL7223[2])/64;
|
||||
EE_Temp = Read_Data_PL7223[3];
|
||||
EE_Temp = EE_Temp << 8;
|
||||
EE_Temp += Read_Data_PL7223[2];
|
||||
VA_rms = (float)EE_Temp/64.00;
|
||||
|
||||
|
||||
//Irms address : 0x3008~0x3009
|
||||
// IA_rms = Read_Data_PL7223[3]+Read_Data_PL7223[2]/256;
|
||||
EE_Temp = Read_Data_PL7223[8];
|
||||
IA_rms = (float)EE_Temp/256.00;
|
||||
EE_Temp = Read_Data_PL7223[9];
|
||||
IA_rms = IA_rms + (float)EE_Temp;
|
||||
|
||||
|
||||
//Active address : 0x3078~0x307D
|
||||
// PA = Read_Data_PL7223[124]*256+Read_Data_PL7223[123];
|
||||
EE_Temp = Read_Data_PL7223[124];
|
||||
EE_Temp = EE_Temp << 8;
|
||||
EE_Temp += Read_Data_PL7223[123];
|
||||
PA = (float)EE_Temp;
|
||||
|
||||
//PF Calculate
|
||||
// SA = VA_rms*IA_rms;
|
||||
SA = VA_rms*IA_rms;
|
||||
// PF_A = PA/SA
|
||||
PF_A = SA==0? 0: PA/SA;
|
||||
Theta_A = acos(PF_A);
|
||||
QA = SA * sin(Theta_A);
|
||||
if(IA_rms==0)
|
||||
Theta_A = 0;
|
||||
else
|
||||
Theta_A = Theta_A * (180.00/(3.141592653589));
|
||||
|
||||
/** Frequency = [Sample_cnt0/(ZCC_STOP-ZCC_START)]*[(ZCC_CNT-1)/2] */
|
||||
Sample_cnt0 = Read_Data_PL7223[145]; // Sample_cnt01
|
||||
Sample_cnt0 = Sample_cnt0 <<8;
|
||||
Sample_cnt0 += Read_Data_PL7223[144]; // Sample_cnt00
|
||||
|
||||
ZCC_cnt = Read_Data_PL7223[91]; // ZCC_cnt1
|
||||
ZCC_cnt = ZCC_cnt <<8;
|
||||
ZCC_cnt += Read_Data_PL7223[90]; // ZCC_cnt0
|
||||
|
||||
ZCC_Stop = Read_Data_PL7223[97]; // ZCC_STOP1
|
||||
ZCC_Stop = ZCC_Stop <<8;
|
||||
ZCC_Stop += Read_Data_PL7223[96]; // ZCC_STOP0
|
||||
|
||||
ZCC_Start = Read_Data_PL7223[103]; // ZCC_START1
|
||||
ZCC_Start = ZCC_Start <<8;
|
||||
ZCC_Start += Read_Data_PL7223[102]; // ZCC_START0
|
||||
|
||||
Frequency = (float)((float)Sample_cnt0 / (ZCC_Stop - ZCC_Start)) * (((float)ZCC_cnt - 1.0) / 2);
|
||||
|
||||
#define UART_Display(name) printf(#name" %d.%d\n\r", (int)(name*1000)/1000, (int)(name*1000)%1000)
|
||||
UART_Display(VA_rms);
|
||||
UART_Display(IA_rms);
|
||||
UART_Display(Frequency);
|
||||
UART_Display(PA);
|
||||
UART_Display(QA);
|
||||
UART_Display(SA);
|
||||
UART_Display(PF_A);
|
||||
UART_Display(Theta_A);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_DELY(int dely_cnt) // MCUCLK 4MHz, Delay-Time 9usec/clock
|
||||
{
|
||||
HalDelayUs(dely_cnt*20);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
void SPI_PL7223_SEND(unsigned char spicmd)
|
||||
{
|
||||
SPDAT = (char)spi_master_write(&spi0_master, (int)spicmd);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use SPI stream read/write by mbed api.
|
||||
|
||||
|
||||
The SPI Interface provides a "Serial Peripheral Interface" Master.
|
||||
|
||||
This interface can be used for communication with SPI slave devices,
|
||||
such as FLASH memory, LCD screens and other modules or integrated circuits.
|
||||
|
||||
|
||||
In this example, we use config SPI_IS_AS_MASTER to decide if device is master or slave.
|
||||
If SPI_IS_AS_MASTER is 1, then device is master.
|
||||
If SPI_IS_AS_MASTER is 0, then device is slave.
|
||||
|
||||
We connect wires as below:
|
||||
master's MOSI (PC_2) connect to slave's MOSI (PC_2)
|
||||
master's MISO (PC_3) connect to slave's MISO (PC_3)
|
||||
master's SCLK (PC_1) connect to slave's SCLK (PC_1)
|
||||
master's CS (PC_0) connect to slave's CS (PC_0)
|
||||
|
||||
This example shows master sends data to slave.
|
||||
We bootup slave first, and then bootup master.
|
||||
Then log will presents that master sending data to slave.
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2014 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "main.h"
|
||||
#include "spi_api.h"
|
||||
#include "spi_ex_api.h"
|
||||
|
||||
#define SPI_IS_AS_MASTER 1
|
||||
#define TEST_BUF_SIZE 2048
|
||||
#define SCLK_FREQ 1000000
|
||||
#define SPI_DMA_DEMO 0
|
||||
#define TEST_LOOP 100
|
||||
|
||||
// SPI0
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0
|
||||
|
||||
_LONG_CALL_ extern
|
||||
void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader);
|
||||
extern void wait_ms(u32);
|
||||
|
||||
char TestBuf[TEST_BUF_SIZE];
|
||||
volatile int TrDone;
|
||||
|
||||
void master_tr_done_callback(void *pdata, SpiIrq event)
|
||||
{
|
||||
TrDone = 1;
|
||||
}
|
||||
|
||||
void slave_tr_done_callback(void *pdata, SpiIrq event)
|
||||
{
|
||||
TrDone = 1;
|
||||
}
|
||||
|
||||
#if SPI_IS_AS_MASTER
|
||||
spi_t spi_master;
|
||||
#else
|
||||
spi_t spi_slave;
|
||||
#endif
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
int Counter = 0;
|
||||
int i;
|
||||
|
||||
#if SPI_IS_AS_MASTER
|
||||
spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
spi_frequency(&spi_master, SCLK_FREQ);
|
||||
spi_format(&spi_master, 16, (SPI_SCLK_IDLE_LOW|SPI_SCLK_TOGGLE_MIDDLE) , 0);
|
||||
// wait Slave ready
|
||||
wait_ms(1000);
|
||||
|
||||
while (Counter < TEST_LOOP) {
|
||||
DBG_8195A("======= Test Loop %d =======\r\n", Counter);
|
||||
|
||||
for (i=0;i<TEST_BUF_SIZE;i++) {
|
||||
TestBuf[i] = i;
|
||||
}
|
||||
|
||||
spi_irq_hook(&spi_master, master_tr_done_callback, (uint32_t)&spi_master);
|
||||
DBG_8195A("SPI Master Write Test==>\r\n");
|
||||
TrDone = 0;
|
||||
#if SPI_DMA_DEMO
|
||||
spi_master_write_stream_dma(&spi_master, TestBuf, TEST_BUF_SIZE);
|
||||
#else
|
||||
spi_master_write_stream(&spi_master, TestBuf, TEST_BUF_SIZE);
|
||||
#endif
|
||||
i=0;
|
||||
DBG_8195A("SPI Master Wait Write Done...\r\n");
|
||||
while(TrDone == 0) {
|
||||
wait_ms(10);
|
||||
i++;
|
||||
}
|
||||
DBG_8195A("SPI Master Write Done!!\r\n");
|
||||
|
||||
DBG_8195A("SPI Master Read Test==>\r\n");
|
||||
DBG_8195A("Wait 5 sec for SPI Slave get ready...\r\n");
|
||||
for (i=0;i<5;i++) {
|
||||
wait_ms(1000);
|
||||
}
|
||||
|
||||
_memset(TestBuf, 0, TEST_BUF_SIZE);
|
||||
spi_flush_rx_fifo(&spi_master);
|
||||
|
||||
TrDone = 0;
|
||||
#if SPI_DMA_DEMO
|
||||
spi_master_read_stream_dma(&spi_master, TestBuf, TEST_BUF_SIZE);
|
||||
#else
|
||||
spi_master_read_stream(&spi_master, TestBuf, TEST_BUF_SIZE);
|
||||
#endif
|
||||
i=0;
|
||||
DBG_8195A("SPI Master Wait Read Done...\r\n");
|
||||
while(TrDone == 0) {
|
||||
wait_ms(10);
|
||||
i++;
|
||||
}
|
||||
DBG_8195A("SPI Master Read Done!!\r\n");
|
||||
__rtl_memDump_v1_00(TestBuf, TEST_BUF_SIZE, "SPI Master Read Data:");
|
||||
Counter++;
|
||||
}
|
||||
spi_free(&spi_master);
|
||||
DBG_8195A("SPI Master Test <==\r\n");
|
||||
|
||||
#else
|
||||
spi_init(&spi_slave, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
spi_format(&spi_slave, 16, (SPI_SCLK_IDLE_LOW|SPI_SCLK_TOGGLE_MIDDLE) , 1);
|
||||
|
||||
while (spi_busy(&spi_slave)) {
|
||||
DBG_8195A("Wait SPI Bus Ready...\r\n");
|
||||
wait_ms(1000);
|
||||
}
|
||||
|
||||
while (Counter < TEST_LOOP) {
|
||||
DBG_8195A("======= Test Loop %d =======\r\n", Counter);
|
||||
_memset(TestBuf, 0, TEST_BUF_SIZE);
|
||||
DBG_8195A("SPI Slave Read Test ==>\r\n");
|
||||
spi_irq_hook(&spi_slave, slave_tr_done_callback, (uint32_t)&spi_slave);
|
||||
TrDone = 0;
|
||||
spi_flush_rx_fifo(&spi_slave);
|
||||
#if SPI_DMA_DEMO
|
||||
spi_slave_read_stream_dma(&spi_slave, TestBuf, TEST_BUF_SIZE);
|
||||
#else
|
||||
spi_slave_read_stream(&spi_slave, TestBuf, TEST_BUF_SIZE);
|
||||
#endif
|
||||
i=0;
|
||||
DBG_8195A("SPI Slave Wait Read Done...\r\n");
|
||||
while(TrDone == 0) {
|
||||
wait_ms(100);
|
||||
i++;
|
||||
if (i>150) {
|
||||
DBG_8195A("SPI Slave Wait Timeout\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
__rtl_memDump_v1_00(TestBuf, TEST_BUF_SIZE, "SPI Slave Read Data:");
|
||||
|
||||
// Slave Write Test
|
||||
DBG_8195A("SPI Slave Write Test ==>\r\n");
|
||||
TrDone = 0;
|
||||
#if SPI_DMA_DEMO
|
||||
spi_slave_write_stream_dma(&spi_slave, TestBuf, TEST_BUF_SIZE);
|
||||
#else
|
||||
spi_slave_write_stream(&spi_slave, TestBuf, TEST_BUF_SIZE);
|
||||
#endif
|
||||
i=0;
|
||||
DBG_8195A("SPI Slave Wait Write Done...\r\n");
|
||||
while(TrDone == 0) {
|
||||
wait_ms(100);
|
||||
i++;
|
||||
if (i> 200) {
|
||||
DBG_8195A("SPI Slave Write Timeout...\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_8195A("SPI Slave Write Done!!\r\n");
|
||||
Counter++;
|
||||
}
|
||||
spi_free(&spi_slave);
|
||||
#endif
|
||||
|
||||
DBG_8195A("SPI Demo finished.\n");
|
||||
for(;;);
|
||||
}
|
||||
24
project/realtek_ameba1_va0_example/example_sources/spi_twoboard/readme.txt
Executable file
24
project/realtek_ameba1_va0_example/example_sources/spi_twoboard/readme.txt
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use SPI read/write by mbed api.
|
||||
|
||||
|
||||
The SPI Interface provides a "Serial Peripheral Interface" Master.
|
||||
|
||||
This interface can be used for communication with SPI slave devices,
|
||||
such as FLASH memory, LCD screens and other modules or integrated circuits.
|
||||
|
||||
|
||||
In this example, we use config SPI_IS_AS_MASTER to decide if device is master or slave.
|
||||
If SPI_IS_AS_MASTER is 1, then device is master.
|
||||
If SPI_IS_AS_MASTER is 0, then device is slave.
|
||||
|
||||
We connect wires as below:
|
||||
master's MOSI (PC_2) connect to slave's MOSI (PC_2)
|
||||
master's MISO (PC_3) connect to slave's MISO (PC_3)
|
||||
master's SCLK (PC_1) connect to slave's SCLK (PC_1)
|
||||
master's CS (PC_0) connect to slave's CS (PC_0)
|
||||
|
||||
This example shows master sends data to slave.
|
||||
We bootup slave first, and then bootup master.
|
||||
Then log will presents that master sending data to slave.
|
||||
64
project/realtek_ameba1_va0_example/example_sources/spi_twoboard/src/main.c
Executable file
64
project/realtek_ameba1_va0_example/example_sources/spi_twoboard/src/main.c
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2014 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "main.h"
|
||||
#include "spi_api.h"
|
||||
|
||||
#define SPI_IS_AS_MASTER 1
|
||||
|
||||
// SPI0
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
int TestingTimes = 10;
|
||||
int Counter = 0;
|
||||
int TestData = 0;
|
||||
|
||||
#if SPI_IS_AS_MASTER
|
||||
spi_t spi_master;
|
||||
|
||||
SPI0_IS_AS_SLAVE = 0;
|
||||
spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
|
||||
DBG_SSI_INFO("--------------------------------------------------------\n");
|
||||
for(Counter = 0, TestData=0xFF; Counter < TestingTimes; Counter++) {
|
||||
spi_master_write(&spi_master, TestData);
|
||||
DBG_SSI_INFO("Master write: %02X\n", TestData);
|
||||
TestData--;
|
||||
}
|
||||
spi_free(&spi_master);
|
||||
|
||||
#else
|
||||
spi_t spi_slave;
|
||||
|
||||
SPI0_IS_AS_SLAVE = 1;
|
||||
spi_init(&spi_slave, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
|
||||
DBG_SSI_INFO("--------------------------------------------------------\n");
|
||||
for(Counter = 0, TestData=0xFF; Counter < TestingTimes; Counter++) {
|
||||
DBG_SSI_INFO(ANSI_COLOR_CYAN"Slave read : %02X\n"ANSI_COLOR_RESET,
|
||||
spi_slave_read(&spi_slave));
|
||||
TestData--;
|
||||
}
|
||||
spi_free(&spi_slave);
|
||||
#endif
|
||||
|
||||
DBG_SSI_INFO("SPI Demo finished.\n");
|
||||
for(;;);
|
||||
}
|
||||
19
project/realtek_ameba1_va0_example/example_sources/uart/readme.txt
Executable file
19
project/realtek_ameba1_va0_example/example_sources/uart/readme.txt
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART to communicate with PC.
|
||||
|
||||
Required Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
Open Super terminal or teraterm and
|
||||
set baud rate to 38400, 1 stopbit, no parity, no flow contorl.
|
||||
|
||||
This example shows:
|
||||
User input will be received by demo board, and demo board will loopback the received character with a prompt string "8195a$".
|
||||
|
||||
46
project/realtek_ameba1_va0_example/example_sources/uart/src/main.c
Executable file
46
project/realtek_ameba1_va0_example/example_sources/uart/src/main.c
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define UART_TX PA_7
|
||||
#define UART_RX PA_6
|
||||
|
||||
void uart_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
unsigned int i=0;
|
||||
|
||||
while (*(pstr+i) != 0) {
|
||||
serial_putc(sobj, *(pstr+i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// sample text
|
||||
char rc;
|
||||
serial_t sobj;
|
||||
|
||||
// mbed uart test
|
||||
serial_init(&sobj,UART_TX,UART_RX);
|
||||
serial_baud(&sobj,38400);
|
||||
serial_format(&sobj, 8, ParityNone, 1);
|
||||
|
||||
uart_send_string(&sobj, "UART API Demo...\r\n");
|
||||
uart_send_string(&sobj, "Hello World!!\r\n");
|
||||
while(1){
|
||||
uart_send_string(&sobj, "\r\n8195a$");
|
||||
rc = serial_getc(&sobj);
|
||||
serial_putc(&sobj, rc);
|
||||
}
|
||||
}
|
||||
|
||||
16
project/realtek_ameba1_va0_example/example_sources/uart_clock/readme.txt
Executable file
16
project/realtek_ameba1_va0_example/example_sources/uart_clock/readme.txt
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART TX to simulate clock source
|
||||
|
||||
Required Components:
|
||||
Oscilloscope
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND of oscilloscope
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect NOTHING
|
||||
GPIOA_7 as UART1_TX connect to probe of oscilloscope
|
||||
|
||||
|
||||
This example shows:
|
||||
1. Clock signal output from UART1_TX to oscilloscope
|
||||
94
project/realtek_ameba1_va0_example/example_sources/uart_clock/src/main.c
Executable file
94
project/realtek_ameba1_va0_example/example_sources/uart_clock/src/main.c
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define UART_TX PA_7
|
||||
#define UART_RX PA_6
|
||||
|
||||
/* 100 bytes data, 500 clocks, provide buadrate/2 frequency */
|
||||
#define SREAM_LEN 128
|
||||
char sim_clock[SREAM_LEN+1];
|
||||
|
||||
|
||||
volatile uint32_t is_stop = 0;
|
||||
static serial_t sobj_clk;
|
||||
|
||||
void uart_clock_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
int32_t ret=0;
|
||||
|
||||
ret = serial_send_stream_dma(sobj, pstr, _strlen(pstr));
|
||||
if (ret != 0) {
|
||||
DBG_8195A("%s Error(%d)\n", __FUNCTION__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
void uart_clock_send_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
if(!is_stop)
|
||||
uart_clock_send_string(sobj, sim_clock);
|
||||
}
|
||||
|
||||
void uart_clock_deinit(void)
|
||||
{
|
||||
is_stop = 1;
|
||||
serial_free(&sobj_clk);
|
||||
}
|
||||
|
||||
void uart_clock_init(int rate)
|
||||
{
|
||||
//serial_t sobj;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i=0;i<SREAM_LEN;i++) {
|
||||
sim_clock[i] = 0x55;
|
||||
}
|
||||
sim_clock[i] = 0;
|
||||
|
||||
serial_init(&sobj_clk,UART_TX,UART_RX);
|
||||
serial_baud(&sobj_clk, rate*2);
|
||||
|
||||
serial_format(&sobj_clk, 8, ParityNone, 0);
|
||||
|
||||
serial_send_comp_handler(&sobj_clk, (void*)uart_clock_send_string_done, (uint32_t) &sobj_clk);
|
||||
}
|
||||
|
||||
void uart_clock_on(void)
|
||||
{
|
||||
is_stop = 0;
|
||||
uart_clock_send_string(&sobj_clk, sim_clock);
|
||||
}
|
||||
|
||||
void uart_clock_off(void)
|
||||
{
|
||||
is_stop = 1;
|
||||
serial_send_stream_abort(&sobj_clk);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// only support 33kHz, 36kHz, 36.7kHz 38kHz, 40kHz, 56kHz
|
||||
uart_clock_init(38000);
|
||||
|
||||
while(1) {
|
||||
uart_clock_on();
|
||||
wait_ms(5000);
|
||||
uart_clock_off();
|
||||
wait_ms(5000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
19
project/realtek_ameba1_va0_example/example_sources/uart_irq/readme.txt
Executable file
19
project/realtek_ameba1_va0_example/example_sources/uart_irq/readme.txt
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART to communicate with PC.
|
||||
|
||||
Required Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
Open Super terminal or teraterm and
|
||||
set baud rate to 38400, 1 stopbit, no parity, no flow contorl.
|
||||
|
||||
This example shows:
|
||||
1. The RX data ready interrupt service routine is used to receive characters from the PC, and then loopback them to the PC.
|
||||
2. The TX done interrupt service routine will send a prompt string "8195a$" to the PC.
|
||||
65
project/realtek_ameba1_va0_example/example_sources/uart_irq/src/main.c
Executable file
65
project/realtek_ameba1_va0_example/example_sources/uart_irq/src/main.c
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define UART_TX PA_7
|
||||
#define UART_RX PA_6
|
||||
|
||||
volatile char rc=0;
|
||||
|
||||
void uart_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
unsigned int i=0;
|
||||
|
||||
while (*(pstr+i) != 0) {
|
||||
serial_putc(sobj, *(pstr+i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_irq(uint32_t id, SerialIrq event)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
|
||||
if(event == RxIrq) {
|
||||
rc = serial_getc(sobj);
|
||||
serial_putc(sobj, rc);
|
||||
}
|
||||
|
||||
if(event == TxIrq && rc!=0){
|
||||
uart_send_string(sobj, "\r\n8195a$");
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// sample text
|
||||
serial_t sobj;
|
||||
|
||||
// mbed uart test
|
||||
serial_init(&sobj,UART_TX,UART_RX);
|
||||
serial_baud(&sobj,38400);
|
||||
serial_format(&sobj, 8, ParityNone, 1);
|
||||
|
||||
uart_send_string(&sobj, "UART IRQ API Demo...\r\n");
|
||||
uart_send_string(&sobj, "Hello World!!\n");
|
||||
uart_send_string(&sobj, "\r\n8195a$");
|
||||
serial_irq_handler(&sobj, uart_irq, (uint32_t)&sobj);
|
||||
serial_irq_set(&sobj, RxIrq, 1);
|
||||
serial_irq_set(&sobj, TxIrq, 1);
|
||||
|
||||
while(1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART to communicate with PC.
|
||||
|
||||
Required Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
Open Super terminal or teraterm and
|
||||
set baud rate to 38400, 1 stopbit, no parity, no flow contorl.
|
||||
|
||||
This example shows:
|
||||
1. The RX data ready interrupt service routine is used to receive characters from the PC, and then loopback them to the PC.
|
||||
2. The TX done interrupt service routine will send a prompt string "8195a$" to the PC.
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
//#include "main.h"
|
||||
|
||||
#define UART_TX PA_7 //PB_5
|
||||
#define UART_RX PA_6 //PB_4
|
||||
|
||||
#define SRX_BUF_SZ 100
|
||||
|
||||
char rx_buf[SRX_BUF_SZ]={0};
|
||||
volatile uint32_t tx_busy=0;
|
||||
volatile uint32_t rx_done=0;
|
||||
|
||||
void uart_send_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
tx_busy = 0;
|
||||
}
|
||||
|
||||
void uart_recv_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
rx_done = 1;
|
||||
}
|
||||
|
||||
void uart_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
int32_t ret=0;
|
||||
|
||||
if (tx_busy) {
|
||||
return;
|
||||
}
|
||||
|
||||
tx_busy = 1;
|
||||
ret = serial_send_stream_dma(sobj, pstr, _strlen(pstr));
|
||||
if (ret != 0) {
|
||||
DBG_8195A("%s Error(%d)\n", __FUNCTION__, ret);
|
||||
tx_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
serial_t sobj;
|
||||
int ret;
|
||||
int i=0;
|
||||
int len;
|
||||
|
||||
serial_init(&sobj,UART_TX,UART_RX);
|
||||
serial_baud(&sobj,38400);
|
||||
serial_format(&sobj, 8, ParityNone, 1);
|
||||
|
||||
serial_send_comp_handler(&sobj, (void*)uart_send_string_done, (uint32_t) &sobj);
|
||||
serial_recv_comp_handler(&sobj, (void*)uart_recv_string_done, (uint32_t) &sobj);
|
||||
|
||||
DBG_8195A("receive 13 bytes\r\n", rx_buf);
|
||||
|
||||
ret = serial_recv_stream_dma(&sobj, rx_buf, 13);
|
||||
if (ret) {
|
||||
DBG_8195A(" %s: Recv Error(%d)\n", __FUNCTION__, ret);
|
||||
rx_done = 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (rx_done) {
|
||||
uart_send_string(&sobj, rx_buf);
|
||||
rx_done = 0;
|
||||
|
||||
len = (i+4) & 0x0f;
|
||||
i++;
|
||||
/* Wait for inputing x character to initiate DMA.
|
||||
8 for this example*/
|
||||
DBG_8195A("rx_len=%d\r\n", len);
|
||||
ret = serial_recv_stream_dma(&sobj, rx_buf, len);
|
||||
rx_buf[len] = 0; // end of string
|
||||
if (ret) {
|
||||
DBG_8195A(" %s: Recv Error(%d)\n", __FUNCTION__, ret);
|
||||
rx_done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART to communicate with PC.
|
||||
|
||||
Required Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
Open Super terminal or teraterm and
|
||||
set baud rate to 38400, 1 stopbit, no parity, no flow contorl.
|
||||
|
||||
This example shows:
|
||||
1. The RX data ready interrupt service routine is used to receive characters from the PC, and then loopback them to the PC.
|
||||
2. The TX done interrupt service routine will send a prompt string "8195a$" to the PC.
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define UART_TX PA_7 //PB_5
|
||||
#define UART_RX PA_6 //PB_4
|
||||
|
||||
#define SRX_BUF_SZ 16
|
||||
|
||||
char rx_buf[SRX_BUF_SZ]={0};
|
||||
volatile uint32_t tx_busy=0;
|
||||
volatile uint32_t rx_done=0;
|
||||
|
||||
void uart_send_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
tx_busy = 0;
|
||||
}
|
||||
|
||||
void uart_recv_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
rx_done = 1;
|
||||
}
|
||||
|
||||
void uart_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
int32_t ret=0;
|
||||
|
||||
if (tx_busy) {
|
||||
return;
|
||||
}
|
||||
|
||||
tx_busy = 1;
|
||||
ret = serial_send_stream(sobj, pstr, _strlen(pstr));
|
||||
if (ret != 0) {
|
||||
DBG_8195A("%s Error(%d)\n", __FUNCTION__, ret);
|
||||
tx_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
serial_t sobj;
|
||||
int ret;
|
||||
|
||||
serial_init(&sobj,UART_TX,UART_RX);
|
||||
serial_baud(&sobj,38400);
|
||||
serial_format(&sobj, 8, ParityNone, 1);
|
||||
|
||||
serial_send_comp_handler(&sobj, (void*)uart_send_string_done, (uint32_t) &sobj);
|
||||
serial_recv_comp_handler(&sobj, (void*)uart_recv_string_done, (uint32_t) &sobj);
|
||||
|
||||
ret = serial_recv_stream(&sobj, rx_buf, 8);
|
||||
if (ret) {
|
||||
DBG_8195A(" %s: Recv Error(%d)\n", __FUNCTION__, ret);
|
||||
rx_done = 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
#if 0
|
||||
if (!tx_busy) {
|
||||
uart_send_string(&sobj, "Hello! World!! :) \r\n");
|
||||
}
|
||||
#endif
|
||||
if (rx_done) {
|
||||
uart_send_string(&sobj, rx_buf);
|
||||
rx_done = 0;
|
||||
ret = serial_recv_stream(&sobj, rx_buf, 8);
|
||||
if (ret) {
|
||||
DBG_8195A(" %s: Recv Error(%d)\n", __FUNCTION__, ret);
|
||||
rx_done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use UART RX API with timeout.
|
||||
|
||||
Required Components:
|
||||
USBtoTTL adapter
|
||||
|
||||
Connect to PC
|
||||
- Connect Ground: connect to GND pin via USBtoTTL adapter
|
||||
- Use UART1
|
||||
GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter
|
||||
GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter
|
||||
|
||||
Open Super terminal or teraterm and
|
||||
set baud rate to 38400, 1 stopbit, no parity, no flow contorl.
|
||||
|
||||
This example shows:
|
||||
1. The RX data ready interrupt service routine is used to receive characters from the PC, and then loopback them to the PC.
|
||||
2. The TX done interrupt service routine will send the received string to the PC.
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define UART_TX PA_7 //PB_5
|
||||
#define UART_RX PA_6 //PB_4
|
||||
|
||||
#define SRX_BUF_SZ 100
|
||||
#define UART_TIMEOUT_MS 5000 //ms
|
||||
|
||||
#define TASK_STACK_SIZE 2048
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
|
||||
char rx_buf[SRX_BUF_SZ]={0};
|
||||
volatile uint32_t rx_bytes=0;
|
||||
SemaphoreHandle_t UartRxSema;
|
||||
SemaphoreHandle_t UartTxSema;
|
||||
|
||||
|
||||
void uart_send_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
xSemaphoreGiveFromISR(UartTxSema, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void uart_recv_string_done(uint32_t id)
|
||||
{
|
||||
serial_t *sobj = (void*)id;
|
||||
signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
rx_bytes = sobj->rx_len;
|
||||
xSemaphoreGiveFromISR(UartRxSema, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void uart_send_string(serial_t *sobj, char *pstr)
|
||||
{
|
||||
int32_t ret=0;
|
||||
|
||||
xSemaphoreTake(UartTxSema, portMAX_DELAY);
|
||||
|
||||
ret = serial_send_stream(sobj, pstr, _strlen(pstr));
|
||||
if (ret != 0) {
|
||||
DBG_8195A("%s Error(%d)\n", __FUNCTION__, ret);
|
||||
xSemaphoreGive( UartTxSema );
|
||||
}
|
||||
}
|
||||
|
||||
void uart_demo(void)
|
||||
{
|
||||
serial_t sobj;
|
||||
int ret;
|
||||
|
||||
serial_init(&sobj,UART_TX,UART_RX);
|
||||
serial_baud(&sobj,115200);
|
||||
serial_format(&sobj, 8, ParityNone, 1);
|
||||
|
||||
serial_send_comp_handler(&sobj, (void*)uart_send_string_done, (uint32_t) &sobj);
|
||||
serial_recv_comp_handler(&sobj, (void*)uart_recv_string_done, (uint32_t) &sobj);
|
||||
|
||||
// Create semaphore for UART RX done(received espected bytes or timeout)
|
||||
UartRxSema = xSemaphoreCreateBinary();
|
||||
|
||||
// Create semaphore for UART TX done
|
||||
UartTxSema = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive( UartTxSema ); // Ready to TX
|
||||
|
||||
while (1) {
|
||||
rx_bytes = 0;
|
||||
#if 1
|
||||
ret = serial_recv_stream(&sobj, rx_buf, 10); // Interrupt mode
|
||||
#else
|
||||
ret = serial_recv_stream_dma(&sobj, rx_buf, 10); // DMA mode
|
||||
#endif
|
||||
if( xSemaphoreTake( UartRxSema, ( TickType_t ) UART_TIMEOUT_MS/portTICK_RATE_MS ) != pdTRUE ) {
|
||||
rx_bytes = serial_recv_stream_abort(&sobj);
|
||||
}
|
||||
|
||||
if (rx_bytes > 0) {
|
||||
rx_buf[rx_bytes] = 0x00; // end of string
|
||||
uart_send_string(&sobj, rx_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// create demo Task
|
||||
if( xTaskCreate( (TaskFunction_t)uart_demo, "UART DEMO", (TASK_STACK_SIZE/4), NULL, TASK_PRIORITY, NULL) != pdPASS) {
|
||||
DBG_8195A("Cannot create demo task\n\r");
|
||||
}
|
||||
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
#error !!!Need FREERTOS!!!
|
||||
#endif
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
10
project/realtek_ameba1_va0_example/example_sources/watchdog/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/watchdog/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use watchdog api.
|
||||
|
||||
Requirement Components: None
|
||||
|
||||
In this example, watchdog is setup to 5s timeout.
|
||||
Watchdog won't bark if we refresh it before timeout.
|
||||
The timer is also reloaded after refresh.
|
||||
Otherwise it will restart system in default or call callback function if registered.
|
||||
61
project/realtek_ameba1_va0_example/example_sources/watchdog/src/main.c
Executable file
61
project/realtek_ameba1_va0_example/example_sources/watchdog/src/main.c
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Routines to access hardware
|
||||
*
|
||||
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "wdt_api.h"
|
||||
|
||||
#define RUN_CALLBACK_IF_WATCHDOG_BARKS (0)
|
||||
|
||||
void dummy_task() {
|
||||
for (int i=0; i<50000000; i++)
|
||||
asm(" nop");
|
||||
}
|
||||
|
||||
void small_task() {
|
||||
printf("\r\ndoing small task...\r\n");
|
||||
dummy_task();
|
||||
printf("refresh watchdog\r\n\r\n");
|
||||
watchdog_refresh();
|
||||
}
|
||||
|
||||
void big_task() {
|
||||
printf("\r\ndoing big task...\r\n");
|
||||
for (int i=0; i<10; i++) {
|
||||
DiagPrintf("doing dummy task %d\r\n", i);
|
||||
dummy_task();
|
||||
}
|
||||
printf("refresh watchdog\r\n\r\n");
|
||||
watchdog_refresh();
|
||||
}
|
||||
|
||||
void my_watchdog_irq_handler(uint32_t id) {
|
||||
printf("watchdog barks!!!\r\n");
|
||||
watchdog_stop();
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
||||
watchdog_init(5000); // setup 5s watchdog
|
||||
|
||||
#if RUN_CALLBACK_IF_WATCHDOG_BARKS
|
||||
watchdog_irq_init(my_watchdog_irq_handler, 0);
|
||||
#else
|
||||
// system would restart when watchdog barks
|
||||
#endif
|
||||
|
||||
watchdog_start();
|
||||
|
||||
small_task();
|
||||
big_task();
|
||||
|
||||
while(1);
|
||||
}
|
||||
14
project/realtek_ameba1_va0_example/example_sources/wlan/readme.txt
Executable file
14
project/realtek_ameba1_va0_example/example_sources/wlan/readme.txt
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use wlan interface.
|
||||
|
||||
PIN assignment
|
||||
|
||||
Wlan is natively support and external gpio pin assign is not required.
|
||||
|
||||
User Mamnual
|
||||
|
||||
Detail information for how to use wi-fi can be found in
|
||||
AN0025 Realtek at command
|
||||
|
||||
|
||||
29
project/realtek_ameba1_va0_example/example_sources/wlan/src/main.c
Executable file
29
project/realtek_ameba1_va0_example/example_sources/wlan/src/main.c
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
|
||||
extern void wlan_netowrk(void);
|
||||
extern void console_init(void);
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
console_init();
|
||||
#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK)
|
||||
wlan_network();
|
||||
#endif
|
||||
|
||||
|
||||
//3 3)Enable Schedule, Start Kernel
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
}
|
||||
202
project/realtek_ameba1_va0_example/inc/FreeRTOSConfig.h
Executable file
202
project/realtek_ameba1_va0_example/inc/FreeRTOSConfig.h
Executable file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||
and contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||
|
||||
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||
the code with commercial support, indemnification, and middleware, under
|
||||
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||
provide a safety engineered and independently SIL3 certified version under
|
||||
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ( ( uint32_t ) 1000 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
|
||||
#ifdef CONFIG_UVC
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 110 * 1024 ) ) // use HEAP5
|
||||
#else
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 60 * 1024 ) ) // use HEAP5
|
||||
#endif
|
||||
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#define configUSE_CO_ROUTINES 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_TIMERS 1
|
||||
|
||||
#define configMAX_PRIORITIES ( 11 )
|
||||
#define PRIORITIE_OFFSET ( 4 )
|
||||
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#if configGENERATE_RUN_TIME_STATS
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //( ulHighFrequencyTimerTicks = 0UL )
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() xTickCount //ulHighFrequencyTimerTicks
|
||||
#undef configUSE_TRACE_FACILITY
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define portCONFIGURE_STATS_PEROID_VALUE 1000 //unit Ticks
|
||||
#endif
|
||||
|
||||
#define configTIMER_TASK_PRIORITY ( 1 )
|
||||
#define configTIMER_QUEUE_LENGTH ( 10 )
|
||||
#define configTIMER_TASK_STACK_DEPTH ( 512 ) // 512*4=2K
|
||||
|
||||
#if (__IASMARM__ != 1)
|
||||
|
||||
extern void freertos_pre_sleep_processing(unsigned int *expected_idle_time);
|
||||
extern int freertos_ready_to_sleep();
|
||||
|
||||
/* Enable tickless power saving. */
|
||||
#define configUSE_TICKLESS_IDLE 1
|
||||
|
||||
/* In wlan usage, this value is suggested to use value less than 80 milliseconds */
|
||||
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
|
||||
|
||||
/* It's magic trick that let us can use our own sleep function */
|
||||
#define configPRE_SLEEP_PROCESSING( x ) ( freertos_pre_sleep_processing(&x) )
|
||||
|
||||
/* It's magic trick that let us can enable/disable tickless dynamically */
|
||||
#define traceLOW_POWER_IDLE_BEGIN(); do { \
|
||||
if (!freertos_ready_to_sleep()) { \
|
||||
mtCOVERAGE_TEST_MARKER(); \
|
||||
break; \
|
||||
}
|
||||
|
||||
// portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
|
||||
|
||||
#define traceLOW_POWER_IDLE_END(); } while (0);
|
||||
|
||||
/* It's FreeRTOS related feature but it's not included in FreeRTOS design. */
|
||||
#define configUSE_WAKELOCK_PMU 1
|
||||
|
||||
#endif // #if (__IASMARM__ != 1)
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_pcTaskGetTaskName 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#define configPRIO_BITS 4 /* 15 priority levels */
|
||||
#endif
|
||||
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
||||
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
//#define RTK_MODE_TIMER
|
||||
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue