mirror of
https://github.com/jialexd/sdk-ameba-v4.0c_180328.git
synced 2026-07-05 11:05:45 +00:00
first add sdk
This commit is contained in:
commit
f91efd1250
3915 changed files with 1291882 additions and 0 deletions
|
|
@ -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);
|
||||
}
|
||||
8
project/realtek_ameba1_va0_example/example_sources/crypto/readme.txt
Executable file
8
project/realtek_ameba1_va0_example/example_sources/crypto/readme.txt
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use CRYPTO function, it is based on cutomer requirement modified.
|
||||
Using mutex_lock to protect HW crypto engine from multiple access concurrently.
|
||||
|
||||
use Arduino board to test, and it will show at console
|
||||
|
||||
|
||||
467
project/realtek_ameba1_va0_example/example_sources/crypto/src/main.c
Executable file
467
project/realtek_ameba1_va0_example/example_sources/crypto/src/main.c
Executable file
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* 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>
|
||||
#include "device_lock.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");
|
||||
|
||||
// Use mutex lock to protect HW crypto engine from multiple access concurrently.
|
||||
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
ret = rtl_crypto_md5(plaintext, strlen(plaintext), (unsigned char *)&digest); // the length of MD5's digest is 16 bytes.
|
||||
|
||||
// Release mutex lock when left critical section.
|
||||
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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 );
|
||||
|
||||
// Use mutex lock to protect HW crypto engine from multiple access concurrently.
|
||||
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
ret = rtl_crypto_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); // the length of MD5's digest is 16 bytes.
|
||||
|
||||
// Release mutex lock when left critical section.
|
||||
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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);
|
||||
|
||||
// Use mutex lock to protect HW crypto engine from multiple access concurrently.
|
||||
// The critical section for encrypt/decrypt should include init function.
|
||||
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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);
|
||||
|
||||
// Release mutex lock when left critical section.
|
||||
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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]);
|
||||
|
||||
// Use mutex lock to protect HW crypto engine from multiple access concurrently.
|
||||
// The critical section for encrypt/decrypt should include init function.
|
||||
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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);
|
||||
|
||||
// Release mutex lock when left critical section.
|
||||
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void test_md5_thread(void *param){
|
||||
test_md5();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void test_aes_cbc_thread(void *param){
|
||||
test_aes_cbc();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void test_aes_ecb_thread(void *param){
|
||||
test_aes_ecb();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/* Note that it should be protected by device_mutex_lock() if using HW crypto */
|
||||
if(xTaskCreate(test_md5_thread, "test_md5_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
|
||||
if(xTaskCreate(test_aes_cbc_thread, "test_aes_cbc_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
|
||||
if(xTaskCreate(test_aes_ecb_thread, "test_aes_ecb_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
|
||||
|
||||
/* 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/efuse_mtp/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/efuse_mtp/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to read/write efuse in MTP.
|
||||
|
||||
MTP block has 32 bytes.
|
||||
|
||||
Requirement Components:
|
||||
None
|
||||
|
||||
|
||||
72
project/realtek_ameba1_va0_example/example_sources/efuse_mtp/src/main.c
Executable file
72
project/realtek_ameba1_va0_example/example_sources/efuse_mtp/src/main.c
Executable file
|
|
@ -0,0 +1,72 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "hal_efuse.h"
|
||||
#include "efuse_api.h"
|
||||
#include "osdep_service.h"
|
||||
#include "device_lock.h"
|
||||
|
||||
#define MTP_MAX_LEN 32 // The MTP max length is 32 bytes
|
||||
static void efuse_mtp_task(void *param)
|
||||
{
|
||||
int ret;
|
||||
u8 i, buf[MTP_MAX_LEN];
|
||||
|
||||
DBG_8195A("\nefuse MTP block: Test Start\n");
|
||||
// read MTP content
|
||||
_memset(buf, 0xFF, MTP_MAX_LEN);
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
efuse_mtp_read(buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
for(i=0; i<MTP_MAX_LEN; i+=8){
|
||||
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
||||
}
|
||||
|
||||
// write MTP content
|
||||
_memset(buf, 0xFF, MTP_MAX_LEN);
|
||||
if(0){ // fill your data
|
||||
for(i=0; i<MTP_MAX_LEN; i++)
|
||||
buf[i] = i;
|
||||
}
|
||||
if(0){ // write
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
ret = efuse_mtp_write(buf, MTP_MAX_LEN);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
if(ret < 0){
|
||||
DBG_8195A("efuse MTP block: write length error\n");
|
||||
goto exit;
|
||||
}
|
||||
DBG_8195A("\nWrite Done\n");
|
||||
DBG_8195A("Remain %d\n", efuse_get_remaining_length());
|
||||
}
|
||||
DBG_8195A("\n");
|
||||
|
||||
// read MTP content
|
||||
_memset(buf, 0xFF, MTP_MAX_LEN);
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
efuse_mtp_read(buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
for(i=0; i<MTP_MAX_LEN; i+=8){
|
||||
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
||||
}
|
||||
|
||||
DBG_8195A("efuse MTP block: Test Done\n");
|
||||
vTaskDelete(NULL);
|
||||
exit:
|
||||
DBG_8195A("efuse MTP block: Test Fail!\n");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if(xTaskCreate(efuse_mtp_task, ((const char*)"efuse_mtp_task"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate(efuse_mtp_task) failed", __FUNCTION__);
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
if(rtw_get_scheduler_state() == OS_SCHEDULER_NOT_STARTED)
|
||||
vTaskStartScheduler();
|
||||
else
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
10
project/realtek_ameba1_va0_example/example_sources/efuse_otp/readme.txt
Executable file
10
project/realtek_ameba1_va0_example/example_sources/efuse_otp/readme.txt
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to read/write efuse in OTP.
|
||||
|
||||
OTP block has 32 bytes.
|
||||
|
||||
Requirement Components:
|
||||
None
|
||||
|
||||
|
||||
81
project/realtek_ameba1_va0_example/example_sources/efuse_otp/src/main.c
Executable file
81
project/realtek_ameba1_va0_example/example_sources/efuse_otp/src/main.c
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "hal_efuse.h"
|
||||
#include "efuse_api.h"
|
||||
#include "osdep_service.h"
|
||||
#include "device_lock.h"
|
||||
|
||||
//======================================================
|
||||
// OTP : one time programming
|
||||
//======================================================
|
||||
|
||||
#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes
|
||||
static void efuse_otp_task(void *param)
|
||||
{
|
||||
int ret;
|
||||
u8 i, buf[OTP_MAX_LEN];
|
||||
|
||||
DBG_8195A("\nefuse OTP block: Test Start\n");
|
||||
// read OTP content
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
ret = efuse_otp_read(0, OTP_MAX_LEN, buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
if(ret < 0){
|
||||
DBG_8195A("efuse OTP block: read address and length error\n");
|
||||
goto exit;
|
||||
}
|
||||
for(i=0; i<OTP_MAX_LEN; i+=8){
|
||||
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
||||
}
|
||||
|
||||
// write OTP content
|
||||
_memset(buf, 0xFF, OTP_MAX_LEN);
|
||||
if(0){ // fill your data
|
||||
for(i=0; i<OTP_MAX_LEN; i++)
|
||||
buf[i] = i;
|
||||
}
|
||||
if(0){ // write
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
ret = efuse_otp_write(0, OTP_MAX_LEN, buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
if(ret < 0){
|
||||
DBG_8195A("efuse OTP block: write address and length error\n");
|
||||
goto exit;
|
||||
}
|
||||
DBG_8195A("\nWrite Done.\n");
|
||||
}
|
||||
DBG_8195A("\n");
|
||||
|
||||
// read OTP content
|
||||
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
||||
ret = efuse_otp_read(0, OTP_MAX_LEN, buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
||||
if(ret < 0){
|
||||
DBG_8195A("efuse OTP block: read address and length error\n");
|
||||
goto exit;
|
||||
}
|
||||
for(i=0; i<OTP_MAX_LEN; i+=8){
|
||||
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
||||
}
|
||||
DBG_8195A("efuse OTP block: Test Done\n");
|
||||
vTaskDelete(NULL);
|
||||
|
||||
exit:
|
||||
DBG_8195A("efuse OTP block: Test Fail!\n");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if(xTaskCreate(efuse_otp_task, ((const char*)"efuse_otp_task"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate(efuse_otp_task) failed", __FUNCTION__);
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
if(rtw_get_scheduler_state() == OS_SCHEDULER_NOT_STARTED)
|
||||
vTaskStartScheduler();
|
||||
else
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
44
project/realtek_ameba1_va0_example/example_sources/ethernet_mii/src/main.c
Executable file
44
project/realtek_ameba1_va0_example/example_sources/ethernet_mii/src/main.c
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include "ethernet_api.h"
|
||||
#include <example_entry.h>
|
||||
|
||||
extern void console_init(void);
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
ethernet_mii_init();// init ethernet driver
|
||||
/* 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
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
119
project/realtek_ameba1_va0_example/example_sources/flash/src/main.c
Executable file
119
project/realtek_ameba1_va0_example/example_sources/flash/src/main.c
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "objects.h"
|
||||
#include "flash_api.h"
|
||||
#include "osdep_service.h"
|
||||
#include "device_lock.h"
|
||||
#include "main.h"
|
||||
|
||||
// Decide starting flash address for storing application data
|
||||
// User should pick address carefully to avoid corrupting image section
|
||||
|
||||
#define FLASH_APP_BASE 0xFF000
|
||||
static void flash_test_task(void *param)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
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);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
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;
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_erase_sector(&flash, address);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
//DBG_8195A("Address = %x \n", address);
|
||||
for(loop = 0; loop < SECTOR_SIZE; loop++){
|
||||
for(index = 0; index < VERIFY_SIZE; index++)
|
||||
{
|
||||
writedata[index] = verifydata + index;
|
||||
}
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_stream_write(&flash, address, VERIFY_SIZE, &writedata);
|
||||
flash_stream_read(&flash, address, VERIFY_SIZE, &readdata);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
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
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if(xTaskCreate(flash_test_task, ((const char*)"flash_test_task"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate(flash_test_task) failed", __FUNCTION__);
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
if(rtw_get_scheduler_state() == OS_SCHEDULER_NOT_STARTED)
|
||||
vTaskStartScheduler();
|
||||
else
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
168
project/realtek_ameba1_va0_example/example_sources/gdma/src/main.c
Executable file
168
project/realtek_ameba1_va0_example/example_sources/gdma/src/main.c
Executable file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
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){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use GPIO read/write in a light weight way.
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
/* You can improve time cost of gpio write by import source code of
|
||||
* function "gpio_direct_write" based on your needs.
|
||||
* In this example, enable CACHE_WRITE_ACTION as demonstration.
|
||||
*/
|
||||
#define CACHE_WRITE_ACTION (0)
|
||||
|
||||
#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1)
|
||||
const u8 _GPIO_SWPORT_DR_TBL[] = {
|
||||
GPIO_PORTA_DR,
|
||||
GPIO_PORTB_DR,
|
||||
GPIO_PORTC_DR
|
||||
};
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1)
|
||||
u8 port_num = HAL_GPIO_GET_PORT_BY_NAME(gpio_led.hal_pin.pin_name);;
|
||||
u8 pin_num = HAL_GPIO_GET_PIN_BY_NAME(gpio_led.hal_pin.pin_name);;
|
||||
u8 dr_tbl = _GPIO_SWPORT_DR_TBL[port_num];
|
||||
u32 RegValue;
|
||||
#endif
|
||||
|
||||
while(1){
|
||||
#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1)
|
||||
if (gpio_read(&gpio_btn)) {
|
||||
// turn off LED
|
||||
RegValue = HAL_READ32(GPIO_REG_BASE, dr_tbl);
|
||||
RegValue &= ~(1 << pin_num);
|
||||
HAL_WRITE32(GPIO_REG_BASE, dr_tbl, RegValue);
|
||||
} else {
|
||||
// turn on LED
|
||||
RegValue = HAL_READ32(GPIO_REG_BASE, dr_tbl);
|
||||
RegValue |= (1<< pin_num);
|
||||
HAL_WRITE32(GPIO_REG_BASE, dr_tbl, RegValue);
|
||||
}
|
||||
#else
|
||||
if (gpio_read(&gpio_btn)) {
|
||||
// turn off LED
|
||||
gpio_direct_write(&gpio_led, 0);
|
||||
} else {
|
||||
// turn on LED
|
||||
gpio_direct_write(&gpio_led, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use microseconds api to generate pulse
|
||||
|
||||
Requirement Components:
|
||||
logical analyser or oscilloscope
|
||||
|
||||
Pin name PC_0 GPIOC_0:
|
||||
- PC_0 as output, connect a logical analyser or oscilloscope
|
||||
|
||||
In this example, PC_0 will generate a pulse with width from 1us to 200us periodically.
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include <stdint.h>
|
||||
#include <example_entry.h>
|
||||
#include "rtl8195a.h"
|
||||
#include "gpio_api.h"
|
||||
|
||||
extern void console_init(void);
|
||||
|
||||
#define GPIO_OUTPUT_PIN PC_0
|
||||
|
||||
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#endif
|
||||
|
||||
#define portOutputRegister(P) ( (volatile uint32_t *)( 0x40001000 + (P) * 0x0C ) )
|
||||
|
||||
void delay( uint32_t ms );
|
||||
void delayMicroseconds(uint32_t us);
|
||||
uint32_t millis( void );
|
||||
uint32_t micros( void );
|
||||
|
||||
void delay( uint32_t ms ) {
|
||||
vTaskDelay(ms);
|
||||
}
|
||||
|
||||
/*
|
||||
* This API implemented from a busy loop with CPU assembly "nop" (no operation).
|
||||
* The accuracy is mostly less than 0.5us. The parameter inside is corrected from
|
||||
* logical analysier. You can try to make it more precisely by changing parameters
|
||||
* inside.
|
||||
**/
|
||||
void delayMicroseconds( uint32_t us ) {
|
||||
int i, j;
|
||||
uint32_t t0, tn;
|
||||
if ( us > 100) {
|
||||
t0 = micros();
|
||||
do {
|
||||
tn = micros();
|
||||
} while ( tn >= t0 && tn < (t0 + us - 1) );
|
||||
} else {
|
||||
for (i=0; i<us; i++) {
|
||||
for (j=0; j<27; j++) {
|
||||
asm("nop");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t millis( void ) {
|
||||
return (__get_IPSR() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR();
|
||||
}
|
||||
|
||||
/*
|
||||
* This API return current system time in unit of microseconds.
|
||||
* It comebines 2 parts: milliseconds and microseconds.
|
||||
* Millisecond is retrieved from system tick.
|
||||
* Microsecond is retrieved from Cortex-M3 CPU clock register.
|
||||
* The microsecond part assumes that CPU clock frequency is 166MHz.
|
||||
* Please note that calling this API would cost around 1~2 microseconds.
|
||||
**/
|
||||
uint32_t micros( void ) {
|
||||
uint32_t tick1, tick2;
|
||||
uint32_t us;
|
||||
|
||||
if (__get_IPSR() == 0) {
|
||||
tick1 = xTaskGetTickCount();
|
||||
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
tick2 = xTaskGetTickCount();
|
||||
} else {
|
||||
tick1 = xTaskGetTickCountFromISR();
|
||||
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
tick2 = xTaskGetTickCountFromISR();
|
||||
}
|
||||
|
||||
if (tick1 == tick2) {
|
||||
return tick1 * 1000 - us / 167;
|
||||
} else if( (us / 167) < 500 ) {
|
||||
return tick1 * 1000 - us / 167;
|
||||
} else {
|
||||
return tick1 * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This thread demonstrate how to use microseconds delay.
|
||||
* In this thread we configure a gpio as output pin and generate pulses with interval from 1us to 200us.
|
||||
* Then delay 2s and repeat again. You can check this signal on logical analyser or oscilloscope with
|
||||
* microsecond precision.
|
||||
*
|
||||
* INPORTANT NOTICE:
|
||||
* The delayMicroseconds API uses CPU clock resource. It means it cannot be interrupted otherwise it
|
||||
* would be out of precision. We disable interrupt before using this API, and then enable interrupt
|
||||
* after that. Thus it sutibles to situation (Ex. IR) that only occupy a short period of time. And
|
||||
* it's not recommended to apply on microseconds lelvel PWM.
|
||||
*/
|
||||
static void delay_demo_thread(void *param) {
|
||||
|
||||
gpio_t gpio_out;
|
||||
uint32_t port, mask;
|
||||
uint32_t delay_interval;
|
||||
|
||||
gpio_init(&gpio_out, GPIO_OUTPUT_PIN);
|
||||
gpio_dir(&gpio_out, PIN_OUTPUT);
|
||||
gpio_mode(&gpio_out, PullNone);
|
||||
gpio_write(&gpio_out, 0);
|
||||
|
||||
port = gpio_out.hal_port_num;
|
||||
mask = 1 << (gpio_out.hal_pin_num);
|
||||
|
||||
while (1) {
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for (delay_interval = 1; delay_interval <=200; delay_interval++) {
|
||||
*portOutputRegister( port ) |= mask;
|
||||
delayMicroseconds( delay_interval );
|
||||
*portOutputRegister( port ) &= ~mask;
|
||||
delayMicroseconds( delay_interval );
|
||||
}
|
||||
taskENABLE_INTERRUPTS();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
/* 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
|
||||
|
||||
/* Execute application example */
|
||||
example_entry();
|
||||
|
||||
if(xTaskCreate(delay_demo_thread, ((const char*)"delay_demo_thread"), 1024, NULL, tskIDLE_PRIORITY+1 , NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate(delay_demo_thread) failed", __FUNCTION__);
|
||||
|
||||
/*Enable Schedule, Start Kernel*/
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
96
project/realtek_ameba1_va0_example/example_sources/gpio_port/src/main.c
Executable file
96
project/realtek_ameba1_va0_example/example_sources/gpio_port/src/main.c
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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};
|
||||
const uint8_t My_Port_Def[] = {
|
||||
PA_6, PA_7, PA_5, PD_4,
|
||||
PD_5, PA_4, PA_3, PA_2,
|
||||
|
||||
0xFF // must end with 0xFF
|
||||
};
|
||||
|
||||
|
||||
extern void wait_ms(u32);
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#if PORT_OUTPUT_TEST
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int pin_mask;
|
||||
|
||||
port_mode(&port0, PullNone);
|
||||
// Assign pins to this port
|
||||
port0.pin_def = (uint8_t *)My_Port_Def;
|
||||
pin_mask = 0xFF; // each bit map to 1 pin: 0: pin disable, 1: pin enable
|
||||
port_init(&port0, PortA, pin_mask, 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;
|
||||
unsigned int pin_mask;
|
||||
int value_new, value_tmp, value_old;
|
||||
int stable;
|
||||
|
||||
port_mode(&port0, PullNone);
|
||||
// Assign pins to this port
|
||||
port0.pin_def = My_Port_Def;
|
||||
pin_mask = 0xFF; // each bit map to 1 pin: 0: pin disable, 1: pin enable
|
||||
port_init(&port0, PortA, pin_mask, 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
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use GPIO read/write mbed api to generate a pulse and to measure the pulse width.
|
||||
|
||||
Requirement Components:
|
||||
a wire
|
||||
|
||||
Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5:
|
||||
- PC_4 as the interrupt GPIO pin with no pull (High-Z).
|
||||
- PC_5 as output to generate a pulse.
|
||||
- Use a wire to connect PC_4 and PC_5
|
||||
|
||||
In this example, the UART consol will print out the measured width (in us) of the pulse which generated by PC_5.
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 "us_ticker_api.h"
|
||||
#include "main.h"
|
||||
|
||||
#define GPIO_OUT_PIN PC_5
|
||||
#define GPIO_IRQ_PIN PC_4
|
||||
|
||||
gpio_t gpio_out;
|
||||
gpio_irq_t gpio_irq;
|
||||
volatile char irq_rise;
|
||||
|
||||
|
||||
void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
static unsigned int rise_time;
|
||||
static unsigned int fall_time;
|
||||
|
||||
if (irq_rise) {
|
||||
rise_time = us_ticker_read();
|
||||
// Changed as Falling Edge Trigger
|
||||
gpio_irq_set_event(&gpio_irq, IRQ_FALL);
|
||||
irq_rise = 0;
|
||||
} else {
|
||||
fall_time = us_ticker_read();
|
||||
// Changed as Rising Edge Trigger
|
||||
gpio_irq_set_event(&gpio_irq, IRQ_RISE);
|
||||
irq_rise = 1;
|
||||
|
||||
DBG_8195A("%d\n", (fall_time-rise_time));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
|
||||
// Init LED control pin
|
||||
gpio_init(&gpio_out, GPIO_OUT_PIN);
|
||||
gpio_dir(&gpio_out, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&gpio_out, PullNone); // No pull
|
||||
gpio_write(&gpio_out, 0);
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&gpio_irq, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_irq));
|
||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 1); // Falling Edge Trigger
|
||||
irq_rise = 1;
|
||||
gpio_irq_pull_ctrl(&gpio_irq, PullNone);
|
||||
gpio_irq_enable(&gpio_irq);
|
||||
|
||||
while(1) {
|
||||
wait_ms(500);
|
||||
gpio_write(&gpio_out, 1);
|
||||
wait_us(1000);
|
||||
gpio_write(&gpio_out, 0);
|
||||
}
|
||||
}
|
||||
|
||||
48
project/realtek_ameba1_va0_example/example_sources/gspi/readme.txt
Executable file
48
project/realtek_ameba1_va0_example/example_sources/gspi/readme.txt
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to communicate with Ameba gspi interface.
|
||||
|
||||
How to build:
|
||||
1. copy src\main.c to project\realtek_ameba1_va0_example\src
|
||||
2. include lib\lib_sdiod.a for build, then re-build the project
|
||||
|
||||
This example source code(mian.c) contain both GSPI slave code and SPI master code, you can use "CONFIG_GPSI_SLAVE" to chose which dirver to run.
|
||||
|
||||
"#define CONFIG_GPSI_SLAVE 1" for GSPI Slave(NOTE: lib_sdiod.a is need for released SDK)
|
||||
"#define CONFIG_GPSI_SLAVE 0" for SPI master
|
||||
|
||||
Requirement Components:
|
||||
2 Ameba DEV_3V0
|
||||
|
||||
Ameba (A): Assign as SPI master
|
||||
|
||||
SCK: PC_1(D13)
|
||||
CS: PB_2(D15)
|
||||
MOSI: PC_2(D11)
|
||||
MISO: PC_3(D12)
|
||||
|
||||
INT: PB_4(D8)
|
||||
|
||||
Ameba (B): Assign as GSPI slave
|
||||
|
||||
SPI_IN: PA_4(D5)
|
||||
SPI_OUT:PA_2(D7)
|
||||
SPI_CLK:PA_3(D6)
|
||||
SPI_CS: PA_1(D16)
|
||||
SPI_INT:PA_5(D2)
|
||||
|
||||
Setup:connect A and B as given
|
||||
|
||||
A: B:
|
||||
|
||||
SCK --- SPI_CLK
|
||||
CS --- SPI_CS
|
||||
MOSI--- SPI_OUT
|
||||
MISO--- SPI_IN
|
||||
INT --- SPI_INT
|
||||
|
||||
V3.3--- V3.3
|
||||
GND --- GND
|
||||
|
||||
Behavior:
|
||||
A send 2048 bytes to B and B will send whatever recived abck to A
|
||||
862
project/realtek_ameba1_va0_example/example_sources/gspi/src/main.c
Executable file
862
project/realtek_ameba1_va0_example/example_sources/gspi/src/main.c
Executable file
|
|
@ -0,0 +1,862 @@
|
|||
/*
|
||||
* 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 "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "rtl8195a_gspi.h"
|
||||
#include "spi_api.h"
|
||||
#include "spi_ex_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "gpio_irq_api.h"
|
||||
#include "osdep_service.h"
|
||||
|
||||
#define CONFIG_GSPI_SLAVE 0
|
||||
#define CONFIG_USE_INTERRUPT 1
|
||||
#define PACK_SIZE 2048
|
||||
|
||||
#if !CONFIG_GSPI_SLAVE
|
||||
|
||||
/*host endian configuration
|
||||
little-endian (1)
|
||||
big-endan (0)
|
||||
*/
|
||||
#define CONFIG_HOST_ENDIAN 1
|
||||
|
||||
// SPI0
|
||||
#define SPI0_MOSI PC_2
|
||||
#define SPI0_MISO PC_3
|
||||
#define SPI0_SCLK PC_1
|
||||
#define SPI0_CS PC_0 // This pin is redundant
|
||||
#if CONFIG_USE_INTERRUPT
|
||||
#define GPIO_INT PB_4 // gspi external interrupt
|
||||
#endif
|
||||
#define GPIO_CS PB_2
|
||||
|
||||
#define SPI0_FREQUENCY 20000000
|
||||
|
||||
static spi_t spi0_master;
|
||||
static gpio_irq_t gpio_int;
|
||||
static gpio_t gpio_cs;
|
||||
|
||||
typedef enum {
|
||||
READ_REG = 0,
|
||||
WRITE_REG
|
||||
}_reg_ops;
|
||||
|
||||
|
||||
// GSPI configuration (big endian recommended)
|
||||
#define GSPI_CONFIG SPI_BIG_ENDIAN_32
|
||||
|
||||
// SPI master configuration
|
||||
#define SPI_BITS 8 // Ameba SPI support 8bits and 16bits mode
|
||||
|
||||
|
||||
struct spi_more_data {
|
||||
unsigned long more_data;
|
||||
unsigned long len;
|
||||
};
|
||||
|
||||
|
||||
#define SLAVE_SELECT() gpio_write(&gpio_cs, 0)
|
||||
#define SLAVE_DESELECT() gpio_write(&gpio_cs, 1)
|
||||
|
||||
#define SPI_DUMMY 0xFF
|
||||
|
||||
// spi interrupt semaphore
|
||||
_sema pspiIrqSemaphore;
|
||||
// spi bus busy
|
||||
_mutex SPIbusbusy;
|
||||
|
||||
volatile bool txDone = FALSE;
|
||||
volatile bool rxDone = FALSE;
|
||||
volatile bool txbusIdle = FALSE;
|
||||
|
||||
|
||||
#define AGG_SIZE 5000
|
||||
#define MAX_DUMMY_LEN 3
|
||||
#define BUFFER_LEN 4+24+PACK_SIZE+8+MAX_DUMMY_LEN // GSPI_CMD + TX_DEC + DATA + GSPI_STATUS
|
||||
|
||||
unsigned char TX_DATA[PACK_SIZE];
|
||||
unsigned char RX_DATA[AGG_SIZE+100]; // extra 100 byte for SDIO header
|
||||
|
||||
unsigned char TX_BUFFER[BUFFER_LEN];
|
||||
unsigned char RX_BUFFER[BUFFER_LEN];
|
||||
|
||||
#endif
|
||||
|
||||
#define TASK_STACK_SIZE 2048
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
|
||||
#if CONFIG_GSPI_SLAVE
|
||||
#include "spdio_api.h"
|
||||
struct spdio_t spdio_dev;
|
||||
|
||||
#define SPDIO_TX_BD_NUM 6 // n*2, must be rounded to 2
|
||||
#define SPDIO_RX_BD_NUM 6 //
|
||||
#define SPDIO_RX_BUFSZ PACK_SIZE+64 //n*64, must be rounded to 64, extra 64 for TX descriptor
|
||||
|
||||
#define CONFIG_RX_BUFFER_REUSE 1
|
||||
|
||||
/*
|
||||
* param: pdata, package
|
||||
*/
|
||||
char ex_gspi_tx(u8 *pdata, u16 size, u8 type){
|
||||
static int rx_cnt = 0;
|
||||
|
||||
// LOOPBACK
|
||||
printf("receive package, size = %d (cnt = %d) heap=%d\n", size, ++rx_cnt, xPortGetFreeHeapSize());
|
||||
|
||||
struct spdio_buf_t *tx_buf = (struct spdio_buf_t *)rtw_malloc(sizeof(struct spdio_buf_t));
|
||||
if(!tx_buf)
|
||||
return FAIL;
|
||||
tx_buf->buf_allocated = (u32)rtw_malloc(size + SPDIO_DMA_ALIGN_4);
|
||||
if(!tx_buf->buf_allocated)
|
||||
{
|
||||
rtw_mfree((u8 *)tx_buf, sizeof(struct spdio_buf_t));
|
||||
return FAIL;
|
||||
}
|
||||
tx_buf->size_allocated = size + SPDIO_DMA_ALIGN_4;
|
||||
|
||||
tx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(tx_buf->buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
|
||||
//printf("buf_addr = %x\n", tx_buf->buf_addr);
|
||||
// copy data
|
||||
memcpy((void*)tx_buf->buf_addr, pdata, size);
|
||||
|
||||
tx_buf->buf_size = size;
|
||||
tx_buf->type = SPDIO_RX_DATA_USER; // you can define your own data type in spdio_rx_data_t and spdio_tx_data_t
|
||||
|
||||
// loopback
|
||||
spdio_tx(&spdio_dev, tx_buf);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*spdio rx done callback (HOST->Device), manage your package and buffer*/
|
||||
char ex_gspi_rx_done_cb(void *priv, void *pbuf, u8 *pdata, u16 size, u8 type){
|
||||
struct spdio_t *obj = (struct spdio_t *)priv;
|
||||
struct spdio_buf_t* rx_buf = (struct spdio_buf_t*)pbuf;
|
||||
|
||||
//2 handle package received
|
||||
ex_gspi_tx(pdata, size, type);
|
||||
|
||||
#if !CONFIG_RX_BUFFER_REUSE
|
||||
// manage rx_buf here
|
||||
rtw_mfree((char *)rx_buf->buf_allocated, rx_buf->size_allocated);
|
||||
|
||||
//2 assign new buffer to RX
|
||||
rx_buf->buf_allocated = (u32)rtw_malloc(obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4);
|
||||
rx_buf->size_allocated = obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4;
|
||||
|
||||
// this buffer must be 4 byte alignment
|
||||
rx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(rx_buf->buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*spdio tx done callback(Device->HOST), manage buffer*/
|
||||
// this API will be called after package have been read by HOST
|
||||
char ex_gspi_tx_done_cb(void *priv, void *pbuf){
|
||||
|
||||
struct spdio_buf_t* tx_buf = (struct spdio_buf_t*)pbuf;
|
||||
|
||||
rtw_mfree((u8 *)tx_buf->buf_allocated, tx_buf->size_allocated);
|
||||
rtw_mfree((u8 *)tx_buf, sizeof(struct spdio_buf_t));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int spi_transfer(uint8_t* buf, uint32_t buf_len)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
rtw_mutex_get(&SPIbusbusy);
|
||||
SLAVE_SELECT();
|
||||
|
||||
txbusIdle = FALSE; // ensure TX done
|
||||
rxDone = FALSE; // ensure RX done
|
||||
|
||||
if(spi_master_write_read_stream(&spi0_master, buf, buf, buf_len)!=0x00){
|
||||
ret = -1;
|
||||
}else{
|
||||
ret = 0;
|
||||
while((!txbusIdle) || (!rxDone)){
|
||||
wait_us(20);
|
||||
if (++i > 2000) {
|
||||
DBG_8195A("SPI write and read Timeout...\r\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Chip Select Pull High */
|
||||
SLAVE_DESELECT();
|
||||
rtw_mutex_put(&SPIbusbusy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int addr_convert(u32 addr)
|
||||
{
|
||||
u32 domain_id = 0 ;
|
||||
u32 temp_addr = addr&0xffff0000;
|
||||
|
||||
switch (temp_addr) {
|
||||
case SPI_LOCAL_OFFSET:
|
||||
domain_id = SPI_LOCAL_DOMAIN;
|
||||
break;
|
||||
case SPI_TX_FIFO_OFFSET:
|
||||
domain_id = SPI_TXFIFO_DOMAIN;
|
||||
break;
|
||||
case SPI_RX_FIFO_OFFSET:
|
||||
domain_id = SPI_RXFIFO_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return domain_id;
|
||||
}
|
||||
|
||||
static inline u32 DWORD_endian_reverse(u32 src, _gspi_conf_t gspi_conf)
|
||||
{
|
||||
u32 temp = 0;
|
||||
switch(gspi_conf){
|
||||
#if CONFIG_HOST_ENDIAN /*host little-endian*/
|
||||
case SPI_LITTLE_ENDIAN_16:
|
||||
temp = (((src&0x000000ff)<<8)|((src&0x0000ff00)>>8)|
|
||||
((src&0x00ff0000)<<8)|((src&0xff000000)>>8));
|
||||
break;
|
||||
case SPI_LITTLE_ENDIAN_32:
|
||||
temp = (((src&0x000000ff)<<24)|((src&0x0000ff00)<<8)|
|
||||
((src&0x00ff0000)>>8)|((src&0xff000000)>>24));
|
||||
break;
|
||||
case SPI_BIG_ENDIAN_16:
|
||||
case SPI_BIG_ENDIAN_32:
|
||||
temp = src;
|
||||
break;
|
||||
#else /*host big-endian*/
|
||||
case SPI_LITTLE_ENDIAN_16:
|
||||
temp = (((src&0x0000ffff)<<16)|((src&0xffff0000)>>16);
|
||||
break;
|
||||
case SPI_LITTLE_ENDIAN_32:
|
||||
temp = src;
|
||||
break;
|
||||
case SPI_BIG_ENDIAN_16:
|
||||
case SPI_BIG_ENDIAN_32:
|
||||
temp = (((src&0x000000ff)<<24)|((src&0x0000ff00)<<8)|
|
||||
((src&0x00ff0000)>>8)|((src&0xff000000)>>24));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* src buffer bit reorder
|
||||
*/
|
||||
static void buf_endian_reverse(u8* src, u32 len, u8* dummy_bytes, _gspi_conf_t gspi_conf)
|
||||
{
|
||||
u32 *buf = (u32*)src;
|
||||
|
||||
u16 count = len/4;
|
||||
u16 remain = len%4;
|
||||
int i = 0;
|
||||
|
||||
if(remain)
|
||||
count ++;
|
||||
|
||||
for(i = 0;i < count; i++){
|
||||
buf[i] = DWORD_endian_reverse(buf[i], gspi_conf);
|
||||
}
|
||||
|
||||
if(remain)
|
||||
*dummy_bytes = 4 - remain;
|
||||
}
|
||||
|
||||
|
||||
int gspi_read_write_reg(_reg_ops ops_type, u32 addr, char * buf, int len,_gspi_conf_t gspi_conf)
|
||||
{
|
||||
int fun = 1, domain_id = 0x0; //LOCAL
|
||||
unsigned int cmd = 0 ;
|
||||
int byte_en = 0 ;//,i = 0 ;
|
||||
int ret = 0;
|
||||
unsigned char status[GSPI_STATUS_LEN] = {0};
|
||||
unsigned int data_tmp = 0;
|
||||
|
||||
u32 spi_buf[4] = {0};
|
||||
|
||||
if (len!=1 && len!=2 && len != 4) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
domain_id = addr_convert(addr);
|
||||
|
||||
addr &= 0x7fff;
|
||||
len &= 0xff;
|
||||
if (ops_type == WRITE_REG) //write register
|
||||
{
|
||||
int remainder = addr % 4;
|
||||
u32 val32 = *(u32 *)buf;
|
||||
switch(len) {
|
||||
case 1:
|
||||
byte_en = (0x1 << remainder);
|
||||
data_tmp = (val32& 0xff)<< (remainder*8);
|
||||
break;
|
||||
case 2:
|
||||
byte_en = (0x3 << remainder);
|
||||
data_tmp = (val32 & 0xffff)<< (remainder*8);
|
||||
break;
|
||||
case 4:
|
||||
byte_en = 0xf;
|
||||
data_tmp = val32 & 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
byte_en = 0xf;
|
||||
data_tmp = val32 & 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //read register
|
||||
{
|
||||
switch(len) {
|
||||
case 1:
|
||||
byte_en = 0x1;
|
||||
break;
|
||||
case 2:
|
||||
byte_en = 0x3;
|
||||
break;
|
||||
case 4:
|
||||
byte_en = 0xf;
|
||||
break;
|
||||
default:
|
||||
byte_en = 0xf;
|
||||
break;
|
||||
}
|
||||
|
||||
if(domain_id == SPI_LOCAL_DOMAIN)
|
||||
byte_en = 0;
|
||||
}
|
||||
|
||||
|
||||
cmd = FILL_SPI_CMD(byte_en, addr, domain_id, fun, ops_type);
|
||||
//4 command segment bytes reorder
|
||||
cmd = DWORD_endian_reverse(cmd, gspi_conf);
|
||||
|
||||
if ((ops_type == READ_REG)&& (domain_id!= SPI_RXFIFO_DOMAIN)) {
|
||||
u32 read_data = 0;
|
||||
|
||||
_memset(spi_buf, 0x00, sizeof(spi_buf));
|
||||
|
||||
//SPI_OUT:32bit cmd
|
||||
//SPI_IN:64bits status+ XXbits data
|
||||
spi_buf[0] = cmd;
|
||||
spi_buf[1] = 0;
|
||||
spi_buf[2] = 0;
|
||||
spi_buf[3] = 0;
|
||||
|
||||
spi_transfer((u8*)spi_buf, sizeof(spi_buf));
|
||||
|
||||
memcpy(status, (u8 *) &spi_buf[1], GSPI_STATUS_LEN);
|
||||
read_data = spi_buf[3];
|
||||
|
||||
*(u32*)buf = DWORD_endian_reverse(read_data, gspi_conf);
|
||||
}
|
||||
else if (ops_type == WRITE_REG ) {
|
||||
//4 data segment bytes reorder
|
||||
data_tmp = DWORD_endian_reverse(data_tmp, gspi_conf);
|
||||
//SPI_OUT:32bits cmd+ XXbits data
|
||||
//SPI_IN:64bits status
|
||||
spi_buf[0] = cmd;
|
||||
spi_buf[1] = data_tmp;
|
||||
spi_buf[2] = 0;
|
||||
spi_buf[3] = 0;
|
||||
|
||||
spi_transfer((u8*)spi_buf, sizeof(spi_buf));
|
||||
|
||||
memcpy(status, (u8 *) &spi_buf[2], GSPI_STATUS_LEN);
|
||||
}
|
||||
|
||||
// translate status
|
||||
return ret;
|
||||
}
|
||||
u8 gspi_read8(u32 addr, s32 *err)
|
||||
{
|
||||
u32 ret = 0;
|
||||
int val32 = 0 , remainder = 0 ;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = gspi_read_write_reg(READ_REG, addr&0xFFFFFFFC, (char *)&ret, 4, GSPI_CONFIG);
|
||||
remainder = addr % 4;
|
||||
val32 = ret;
|
||||
val32 = (val32& (0xff<< (remainder<<3)))>>(remainder<<3);
|
||||
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return (u8)val32;
|
||||
|
||||
}
|
||||
|
||||
|
||||
u16 gspi_read16(u32 addr, s32 *err)
|
||||
{
|
||||
u32 ret = 0;
|
||||
int val32 = 0 , remainder = 0 ;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = gspi_read_write_reg(READ_REG, addr&0xFFFFFFFC,(char *)&ret, 4, GSPI_CONFIG);
|
||||
remainder = addr % 4;
|
||||
val32 = ret;
|
||||
val32 = (val32& (0xffff<< (remainder<<3)))>>(remainder<<3);
|
||||
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return (u16)val32;
|
||||
}
|
||||
|
||||
|
||||
u32 gspi_read32(u32 addr, s32 *err)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
s32 _err = 0;
|
||||
|
||||
_err = gspi_read_write_reg(READ_REG, addr&0xFFFFFFFC,(char *)&ret,4 ,GSPI_CONFIG);
|
||||
if (err)
|
||||
*err = _err;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
s32 gspi_write8(u32 addr, u8 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = gspi_read_write_reg(WRITE_REG, addr, (char *)&buf,1, GSPI_CONFIG);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 gspi_write16(u32 addr, u16 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = gspi_read_write_reg(WRITE_REG,addr,(char *)&buf,2, GSPI_CONFIG);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 gspi_write32(u32 addr, u32 buf, s32 *err)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = gspi_read_write_reg(WRITE_REG, addr,(char *)&buf,4, GSPI_CONFIG);
|
||||
if (err)
|
||||
*err = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gspi_read_rx_fifo(u8 *buf, u32 len, struct spi_more_data * pmore_data,_gspi_conf_t gspi_conf)
|
||||
{
|
||||
int fun = 1;
|
||||
u32 cmd = 0;
|
||||
u8* spi_buf = (u8 *) (buf);
|
||||
u8* spi_data = spi_buf + GSPI_CMD_LEN;
|
||||
u8* spi_status = spi_data + len;
|
||||
int spi_buf_len = GSPI_CMD_LEN + N_BYTE_ALIGMENT(len, 4) + GSPI_STATUS_LEN;
|
||||
u8 dummy_bytes = 0;
|
||||
|
||||
cmd = FILL_SPI_CMD(len, ((len&0xff00) >>8), SPI_RXFIFO_DOMAIN, fun, (unsigned int)0);
|
||||
|
||||
//4 command segment bytes reorder
|
||||
cmd = DWORD_endian_reverse(cmd, gspi_conf);
|
||||
memcpy(spi_buf, (u8 *)&cmd, GSPI_CMD_LEN);
|
||||
//4 clean data segment
|
||||
memset(spi_data,0x00, len);
|
||||
//4 clean status segment
|
||||
memset(spi_status, 0x00, GSPI_STATUS_LEN);
|
||||
|
||||
spi_transfer((u8 *) spi_buf, spi_buf_len);
|
||||
|
||||
// data segement reorder
|
||||
buf_endian_reverse(spi_data, len, &dummy_bytes, gspi_conf);
|
||||
// status segment reorder
|
||||
spi_status += dummy_bytes;
|
||||
buf_endian_reverse(spi_status, GSPI_STATUS_LEN, &dummy_bytes, gspi_conf);
|
||||
|
||||
pmore_data->more_data = GET_STATUS_HISR(spi_status) & SPI_HIMR_RX_REQUEST_MSK;
|
||||
pmore_data->len = GET_STATUS_RXQ_REQ_LEN(spi_status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gspi_write_tx_fifo(u8 *buf, u32 len, _gspi_conf_t gspi_conf)
|
||||
{
|
||||
int fun = 1; //TX_HIQ_FIFO
|
||||
unsigned int cmd = 0;
|
||||
u8 *spi_buf = (u8 *) (buf);
|
||||
u8* spi_data = spi_buf + GSPI_CMD_LEN;
|
||||
u8* spi_status;// = buf + len
|
||||
u32 spi_buf_len = 0;
|
||||
|
||||
u32 NumOfFreeSpace;
|
||||
u8 wait_num = 0;
|
||||
u8 dummy_bytes = 0;
|
||||
|
||||
NumOfFreeSpace = gspi_read32(LOCAL_REG_FREE_TX_SPACE, NULL);
|
||||
|
||||
while (NumOfFreeSpace * (PACK_SIZE+SIZE_TX_DESC) < len) {
|
||||
if((++wait_num) >= 4){
|
||||
DBG_8195A("%s(): wait_num is >= 4\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
RtlUdelayOS(100); //delay 100us
|
||||
NumOfFreeSpace = gspi_read32(LOCAL_REG_FREE_TX_SPACE, NULL);
|
||||
}
|
||||
cmd = FILL_SPI_CMD(len, ((len&0xff00) >>8), SPI_TXFIFO_DOMAIN, fun, (unsigned int)1);
|
||||
//4 command segment bytes reorder
|
||||
cmd = DWORD_endian_reverse(cmd, gspi_conf);
|
||||
memcpy(spi_buf, (u8 *)&cmd, GSPI_CMD_LEN);
|
||||
|
||||
//4 data segment bytes reorder
|
||||
buf_endian_reverse(spi_data, len, &dummy_bytes, gspi_conf);
|
||||
|
||||
//4 status segment
|
||||
spi_status = spi_data + len + dummy_bytes;
|
||||
memset(spi_status, 0x00, GSPI_STATUS_LEN);
|
||||
|
||||
spi_buf_len = GSPI_CMD_LEN + len + dummy_bytes + GSPI_STATUS_LEN;
|
||||
|
||||
spi_transfer((u8 *) spi_buf, spi_buf_len);
|
||||
|
||||
// parse status infomation
|
||||
// GET_STATUS_HISR(status)
|
||||
// GET_STATUS_FREE_TX(status)
|
||||
// GET_STATUS_RXQ_REQ_LEN(status)
|
||||
// GET_STATUS_TX_SEQ(status)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gspi_write_page(u8 *buf, u32 len, u8 agg_cnt){
|
||||
int res;
|
||||
u32 tot_len = SIZE_TX_DESC + len;
|
||||
PGSPI_TX_DESC ptxdesc;
|
||||
|
||||
// clean GSPI command and tx descriptor area
|
||||
memset(TX_BUFFER, 0, GSPI_CMD_LEN+SIZE_TX_DESC);
|
||||
|
||||
ptxdesc = (PGSPI_TX_DESC)(TX_BUFFER + GSPI_CMD_LEN); // reserve 4 byte for GSPI cmd
|
||||
ptxdesc->txpktsize = len;
|
||||
ptxdesc->offset = SIZE_TX_DESC;
|
||||
ptxdesc->bus_agg_num = agg_cnt;
|
||||
ptxdesc->type = GSPI_CMD_TX;
|
||||
|
||||
memcpy(TX_BUFFER+GSPI_CMD_LEN+SIZE_TX_DESC, buf, len);
|
||||
|
||||
res = gspi_write_tx_fifo(TX_BUFFER, tot_len, GSPI_CONFIG);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int gspi_configuration(_gspi_conf_t gspi_conf){
|
||||
|
||||
u8 conf = gspi_conf;
|
||||
u8 retry_t = 0;
|
||||
|
||||
retry:
|
||||
/*GSPI default mode: SPI_LITTLE_ENDIAN_32*/
|
||||
gspi_read_write_reg(WRITE_REG, SPI_LOCAL_OFFSET|SPI_REG_SPI_CFG,(char *)&conf,1 ,SPI_LITTLE_ENDIAN_32);
|
||||
|
||||
// read gspi config
|
||||
conf = 0xff;
|
||||
conf = gspi_read8(SPI_LOCAL_OFFSET|SPI_REG_SPI_CFG, NULL);
|
||||
|
||||
if(conf != gspi_conf){
|
||||
if(++ retry_t <= 3)
|
||||
goto retry;
|
||||
DBG_8195A("%s: config fail@ 0x%x\n", __FUNCTION__, conf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *s;
|
||||
switch (conf) {
|
||||
case SPI_LITTLE_ENDIAN_16:
|
||||
s = "LITTLE_ENDIAN|WORD_LEN_16"; break;
|
||||
case SPI_LITTLE_ENDIAN_32:
|
||||
s = "LITTLE_ENDIAN|WORD_LEN_32"; break;
|
||||
case SPI_BIG_ENDIAN_16:
|
||||
s = "BIG_ENDIAN|WORD_LEN_16"; break;
|
||||
case SPI_BIG_ENDIAN_32:
|
||||
s = "BIG_ENDIAN|WORD_LEN_32"; break;
|
||||
default:
|
||||
s = "UNKNOW CONFIGURATION"; break;
|
||||
};
|
||||
DBG_8195A("%s: Current configuration:%s\n", __FUNCTION__, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_USE_INTERRUPT
|
||||
void spi_interrupt_thread(){
|
||||
u32 spi_hisr;
|
||||
u32 spi_himr;
|
||||
u32 rx_cnt = 0;
|
||||
while(1){
|
||||
if (rtw_down_sema(&pspiIrqSemaphore) == _FAIL){
|
||||
DBG_8195A("%s, Take Semaphore Fail\n", __FUNCTION__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spi_himr = gspi_read32(SPI_LOCAL_OFFSET | SPI_REG_HIMR, NULL);
|
||||
spi_hisr = gspi_read32(SPI_LOCAL_OFFSET | SPI_REG_HISR, NULL);
|
||||
|
||||
if (spi_hisr & spi_himr){
|
||||
if(spi_hisr & SPI_HISR_RX_REQUEST) {
|
||||
u8* rx_buf = NULL;
|
||||
u8* payload = NULL;
|
||||
u32 rx_len = 0;
|
||||
u8 rx_len_rdy = 0;
|
||||
PGSPI_RX_DESC prxdesc;
|
||||
struct spi_more_data more_data = {0};
|
||||
|
||||
// clean RX buffer
|
||||
memset(RX_DATA, 0, AGG_SIZE + 100);
|
||||
rx_buf = RX_DATA;
|
||||
|
||||
do {
|
||||
//validate RX_LEN_RDY before reading RX0_REQ_LEN
|
||||
if(rx_len==0){
|
||||
rx_len_rdy = gspi_read8(SPI_LOCAL_OFFSET|(SPI_REG_RX0_REQ_LEN + 3), NULL);
|
||||
if(rx_len_rdy & BIT7){
|
||||
rx_len = (gspi_read32(SPI_LOCAL_OFFSET | SPI_REG_RX0_REQ_LEN, NULL)) &0xffffff;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_len >(PACK_SIZE+SIZE_RX_DESC))
|
||||
rx_len = PACK_SIZE+SIZE_RX_DESC;
|
||||
|
||||
if(rx_len){
|
||||
|
||||
memset(RX_BUFFER, 0, BUFFER_LEN);
|
||||
|
||||
gspi_read_rx_fifo(RX_BUFFER, rx_len, &more_data,GSPI_CONFIG);
|
||||
|
||||
memcpy(rx_buf, RX_BUFFER+GSPI_CMD_LEN, rx_len);
|
||||
|
||||
prxdesc = (PGSPI_RX_DESC)rx_buf;
|
||||
|
||||
DBG_8195A("Receive Data lenth = %d (cnt = %d)\n",prxdesc->pkt_len, ++rx_cnt);
|
||||
|
||||
payload = rx_buf + prxdesc->offset;
|
||||
rx_buf += rx_len;
|
||||
rx_len = 0;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while(1);
|
||||
}
|
||||
}
|
||||
// query other interrupt here
|
||||
}
|
||||
exit:
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// external GSPI interrupt handler
|
||||
void gspi_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
//DBG_8195A("gspi_irq_handler....\n");
|
||||
if(!pspiIrqSemaphore)
|
||||
return;
|
||||
rtw_up_sema_from_isr(&pspiIrqSemaphore);
|
||||
}
|
||||
|
||||
// SPI master interrupt callback if use interrupt mode
|
||||
void spi_tx_rx_intr_callback(void *pdata, SpiIrq event){
|
||||
|
||||
switch(event){
|
||||
case SpiRxIrq:
|
||||
rxDone = TRUE;
|
||||
break;
|
||||
case SpiTxIrq:
|
||||
txDone = TRUE;
|
||||
break;
|
||||
default:
|
||||
DBG_8195A("unknown interrput evnent!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void spi_tx_bus_idle_callback(void *pdata, SpiIrq event){
|
||||
txbusIdle = TRUE;
|
||||
}
|
||||
|
||||
void spi_init_intr(){
|
||||
#if CONFIG_USE_INTERRUPT
|
||||
// init gspi external interrupt
|
||||
gpio_irq_init(&gpio_int, GPIO_INT, gspi_irq_handler, NULL);
|
||||
gpio_irq_set(&gpio_int, INT_FALLING, 1); // Falling Edge Trigger
|
||||
gpio_irq_enable(&gpio_int);
|
||||
#endif
|
||||
// init spi master tx/rx done interrupt
|
||||
spi_irq_hook(&spi0_master, (spi_irq_handler)spi_tx_rx_intr_callback, NULL);
|
||||
|
||||
// init spi master tx bus idle interrupt
|
||||
spi_bus_tx_done_irq_hook(&spi0_master, (spi_irq_handler)spi_tx_bus_idle_callback, NULL);
|
||||
}
|
||||
void spi_init_master(){
|
||||
// init spi master
|
||||
spi_init(&spi0_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
|
||||
spi_format(&spi0_master, SPI_BITS, 0, 0);
|
||||
spi_frequency(&spi0_master, SPI0_FREQUENCY);
|
||||
printf("spi master frequency %d Hz\n",SPI0_FREQUENCY);
|
||||
|
||||
gpio_init(&gpio_cs, GPIO_CS);
|
||||
gpio_mode(&gpio_cs, PullDown);
|
||||
gpio_dir(&gpio_cs, PIN_OUTPUT);
|
||||
|
||||
SLAVE_DESELECT(); // deselect slave
|
||||
}
|
||||
#endif
|
||||
|
||||
void gspi_demo(void)
|
||||
{
|
||||
#if CONFIG_GSPI_SLAVE
|
||||
int i;
|
||||
|
||||
DBG_8195A("Init GSPI slave....\n");
|
||||
|
||||
spdio_dev.priv = NULL;
|
||||
spdio_dev.rx_bd_num = SPDIO_RX_BD_NUM;
|
||||
spdio_dev.tx_bd_num = SPDIO_TX_BD_NUM;
|
||||
spdio_dev.rx_bd_bufsz = SPDIO_RX_BUFSZ;
|
||||
|
||||
spdio_dev.rx_buf = (struct spdio_buf_t *)rtw_malloc(SPDIO_RX_BD_NUM*sizeof(struct spdio_buf_t));
|
||||
|
||||
for(i=0;i<SPDIO_RX_BD_NUM;i++){
|
||||
spdio_dev.rx_buf[i].buf_allocated = (u32)rtw_malloc(SPDIO_RX_BUFSZ + SPDIO_DMA_ALIGN_4);
|
||||
if(!spdio_dev.rx_buf[i].buf_allocated){
|
||||
printf("malloc failed for spdio buffer!\n");
|
||||
return;
|
||||
}
|
||||
spdio_dev.rx_buf[i].size_allocated = SPDIO_RX_BUFSZ + SPDIO_DMA_ALIGN_4;
|
||||
// this buffer must be 4 byte alignment
|
||||
spdio_dev.rx_buf[i].buf_addr = (u32)N_BYTE_ALIGMENT((u32)(spdio_dev.rx_buf[i].buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
}
|
||||
|
||||
spdio_dev.rx_done_cb = ex_gspi_rx_done_cb;
|
||||
spdio_dev.tx_done_cb = ex_gspi_tx_done_cb;
|
||||
|
||||
DBG_INFO_MSG_OFF(_DBG_SDIO_);
|
||||
DBG_WARN_MSG_OFF(_DBG_SDIO_);
|
||||
DBG_ERR_MSG_ON(_DBG_SDIO_);
|
||||
|
||||
spdio_init(&spdio_dev);
|
||||
#else
|
||||
DBG_8195A("Init SPI master....\n");
|
||||
u32 spi_himr = 0;
|
||||
u32 spi_hisr = 0;
|
||||
u32 spi_ictlr = 0;
|
||||
u32 rx_agg_ctrl = 0;
|
||||
s8 res = 0;
|
||||
int test_loop = 1000;
|
||||
|
||||
//1 SPI host init
|
||||
spi_init_master();
|
||||
spi_init_intr();
|
||||
|
||||
rtw_init_sema(&pspiIrqSemaphore, 0);
|
||||
// used for sync SPI bus, SPI bus shold not be interrupt
|
||||
rtw_mutex_init(&SPIbusbusy);
|
||||
|
||||
if( xTaskCreate( (TaskFunction_t)spi_interrupt_thread, "SPI INTERRUPT", (TASK_STACK_SIZE/4), NULL, TASK_PRIORITY+2, NULL) != pdPASS) {
|
||||
DBG_8195A("Cannot create SPI INTERRUPT task\n\r");
|
||||
goto err;
|
||||
}
|
||||
|
||||
//1 GSPI slave configuration
|
||||
res = gspi_configuration(GSPI_CONFIG);
|
||||
if(res){
|
||||
DBG_8195A("gspi configure error....\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
// INT_CTRL-clean INT control register
|
||||
spi_ictlr = 0;
|
||||
gspi_write32(SPI_LOCAL_OFFSET |SPI_REG_INT_CTRL, spi_ictlr, NULL);
|
||||
|
||||
// HISR - clean interrupt status register
|
||||
gspi_write32(SPI_LOCAL_OFFSET |SPI_REG_HISR, 0xFFFFFFFF, NULL);
|
||||
|
||||
// HIMR - turn all off
|
||||
gspi_write32(SPI_LOCAL_OFFSET |SPI_REG_HIMR, SPI_HIMR_DISABLED, NULL);
|
||||
|
||||
// Set intterrupt mask
|
||||
spi_himr = (u32)(SPI_HISR_RX_REQUEST|SPI_HISR_CPWM1_INT);
|
||||
|
||||
// Write and enable interrupt
|
||||
gspi_write32(SPI_LOCAL_OFFSET | SPI_REG_HIMR, spi_himr, NULL);
|
||||
|
||||
#if 1
|
||||
// set RX AGG control register
|
||||
rx_agg_ctrl = 0;
|
||||
gspi_write32(SPI_LOCAL_OFFSET | SPI_REG_RX_AGG_CTL, rx_agg_ctrl, NULL);
|
||||
#endif
|
||||
|
||||
// prepare test data (0x00-0xFF, 0x00-0xFF......)
|
||||
for(int i=0;i<PACK_SIZE;i++)
|
||||
memset(TX_DATA+i, i%256, 1);
|
||||
|
||||
do{
|
||||
res = gspi_write_page(TX_DATA, PACK_SIZE, 1);
|
||||
if(res) {
|
||||
DBG_8195A("spi_write_page: Error!");
|
||||
// handle error msg here
|
||||
}
|
||||
rtw_mdelay_os(10);
|
||||
}while(--test_loop);
|
||||
|
||||
#if !CONFIG_USE_INTERRUPT
|
||||
|
||||
#endif
|
||||
#endif
|
||||
err:
|
||||
//
|
||||
// spi_free(&spi0_master);
|
||||
|
||||
/* Kill init thread after all init tasks done */
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// create demo Task
|
||||
if( xTaskCreate( (TaskFunction_t)gspi_demo, "GSPI 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
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* This example should work accompany by other examples
|
||||
* 1. project\realtek_ameba1_va0_example\example_sources\gspi
|
||||
* 2. project\realtek_ameba1_va0_example\example_sources\gspi_fw_loader
|
||||
*/
|
||||
|
||||
Example Description
|
||||
|
||||
This example describes how to download encrypted firmware to slave and do loopback test.
|
||||
|
||||
copy "src/main.c" to cover the original ones under the default project path.
|
||||
|
||||
|
||||
Requirement Components:
|
||||
2 Ameba DEV_3V0
|
||||
|
||||
Ameba 8195AM(A): Assign as SPI master
|
||||
|
||||
SCK: PC_1(D13)
|
||||
CS: PB_2(D15)
|
||||
MOSI: PC_2(D11)
|
||||
MISO: PC_3(D12)
|
||||
|
||||
INT: PB_4(D8)
|
||||
|
||||
Ameba 8711AF/AN(B): Assign as GSPI slave (must be configured as boot from SDIO)
|
||||
|
||||
SPI_IN: PA_4(D5)
|
||||
SPI_OUT:PA_2(D7)
|
||||
SPI_CLK:PA_3(D6)
|
||||
SPI_CS: PA_1(D16)
|
||||
SPI_INT:PA_5(D2)
|
||||
|
||||
Build bin files:
|
||||
In order to run this demo, at least three **.bin should be generated seperately with diffrent example sources.
|
||||
1. project\realtek_ameba1_va0_example\example_sources\gspi_fw_downloader\src\main.c
|
||||
(A) Ram_all.bin : Host firmware downloader
|
||||
Use #define OAT_CIPHER_TYPE to config the encryption status of firmware to be download (ota.bin)
|
||||
#define OTA_CIPHER_TYPE 0 // NONE encryption (defualt)
|
||||
#define OTA_CIPHER_TYPE 1 // AES_128_CBC encryption
|
||||
|
||||
2. project\realtek_ameba1_va0_example\example_sources\gspi_fw_loader\src\main.c
|
||||
(B) Ram_all.bin : Slave firmware loader
|
||||
|
||||
2. project\realtek_ameba1_va0_example\example_sources\gspi\src\main.c
|
||||
(c) Ota.bin: Slave test firmware. generated by config #define CONFIG_GPSI_SLAVE 1
|
||||
(D) Ota.e.bin: Encypted ota.bin
|
||||
Encrypte ota.bin according to configuration(OTA_CIPHER_TYPE) when generate firmware (A).
|
||||
If(#define OTA_CIPHER_TYPE 1), use EncryptTools (encrypt.bat) to generate ota.e.bin.
|
||||
|
||||
|
||||
Demo setup:
|
||||
Use ImageTool.exe to load firmware (B) and (C)or(D) to host end flash at customized image erea.
|
||||
(Highly Recommended: Erase the whole flash first)
|
||||
|
||||
#if (#define OTA_CIPHER_TYPE 0)
|
||||
1. load (C) to address 0xB1000 // #define OTA_ADDR 0x000B1000 in main.c
|
||||
#else(#define OTA_CIPHER_TYPE 1)
|
||||
1. load (D) to address 0xB1000 // #define OTA_ADDR 0x000B1000 in main.c
|
||||
#endif
|
||||
|
||||
2. load (B) to address 0x91000 // #define RAM_ALL_ADDR 0x00091000 in main.c
|
||||
|
||||
3. Download (A) to host as usual method.
|
||||
|
||||
|
||||
connect Ameba A and B as given
|
||||
|
||||
A: B:
|
||||
|
||||
SCK --- SPI_CLK
|
||||
CS --- SPI_CS
|
||||
MOSI--- SPI_OUT
|
||||
MISO--- SPI_IN
|
||||
INT --- SPI_INT
|
||||
|
||||
V3.3--- V3.3
|
||||
GND --- GND
|
||||
|
||||
Behavior:
|
||||
1. Slave end boot from SDIO, waiting master end download firmware (ram_all.bin + ota.bin or ota.e.bin)
|
||||
2. Master end download firmware to slave end, and wait slave firmware ready
|
||||
3. Master begin to do loopback test.
|
||||
1452
project/realtek_ameba1_va0_example/example_sources/gspi_fw_downloader/src/main.c
Executable file
1452
project/realtek_ameba1_va0_example/example_sources/gspi_fw_downloader/src/main.c
Executable file
File diff suppressed because it is too large
Load diff
85
project/realtek_ameba1_va0_example/example_sources/gspi_fw_loader/readme.txt
Executable file
85
project/realtek_ameba1_va0_example/example_sources/gspi_fw_loader/readme.txt
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This example should work accompany by other examples
|
||||
* 1. project\realtek_ameba1_va0_example\example_sources\gspi
|
||||
* 2. project\realtek_ameba1_va0_example\example_sources\gspi_fw_downloader
|
||||
*/
|
||||
|
||||
Example Description
|
||||
|
||||
This example describes how to download encrypted firmware to slave and do loopback test.
|
||||
|
||||
How to build:
|
||||
1. copy src\main.c to project\realtek_ameba1_va0_example\src
|
||||
2. include lib\lib_sdiod.a for build, then re-build the project
|
||||
|
||||
|
||||
Requirement Components:
|
||||
2 Ameba DEV_3V0
|
||||
|
||||
Ameba 8195AM(A): Assign as SPI master
|
||||
|
||||
SCK: PC_1(D13)
|
||||
CS: PB_2(D15)
|
||||
MOSI: PC_2(D11)
|
||||
MISO: PC_3(D12)
|
||||
|
||||
INT: PB_4(D8)
|
||||
|
||||
Ameba 8711AF/AN(B): Assign as GSPI slave (must be configured as boot from SDIO)
|
||||
|
||||
SPI_IN: PA_4(D5)
|
||||
SPI_OUT:PA_2(D7)
|
||||
SPI_CLK:PA_3(D6)
|
||||
SPI_CS: PA_1(D16)
|
||||
SPI_INT:PA_5(D2)
|
||||
|
||||
Build bin files:
|
||||
In order to run this demo, at least three **.bin should be generated seperately with diffrent example sources.
|
||||
1. project\realtek_ameba1_va0_example\example_sources\gspi_fw_downloader\src\main.c
|
||||
(A) Ram_all.bin : Host firmware downloader
|
||||
Use #define OAT_CIPHER_TYPE to config the encryption status of firmware to be download (ota.bin)
|
||||
#define OTA_CIPHER_TYPE 0 // NONE encryption (defualt)
|
||||
#define OTA_CIPHER_TYPE 1 // AES_128_CBC encryption
|
||||
|
||||
2. project\realtek_ameba1_va0_example\example_sources\gspi_fw_loader\src\main.c
|
||||
(B) Ram_all.bin : Slave firmware loader
|
||||
|
||||
2. project\realtek_ameba1_va0_example\example_sources\gspi\src\main.c
|
||||
(c) Ota.bin: Slave test firmware. generated by config #define CONFIG_GPSI_SLAVE 1
|
||||
(D) Ota.e.bin: Encypted ota.bin
|
||||
Encrypte ota.bin according to configuration(OTA_CIPHER_TYPE) when generate firmware (A).
|
||||
If(#define OTA_CIPHER_TYPE 1), use EncryptTools (encrypt.bat) to generate ota.e.bin.
|
||||
|
||||
|
||||
Demo setup:
|
||||
Use ImageTool.exe to load firmware (B) and (C)or(D) to host end flash at customized image erea.
|
||||
(Highly Recommended: Erase the whole flash first)
|
||||
|
||||
#if (#define OTA_CIPHER_TYPE 0)
|
||||
1. load (C) to address 0xB1000 // #define OTA_ADDR 0x000B1000 in main.c
|
||||
#else(#define OTA_CIPHER_TYPE 1)
|
||||
1. load (D) to address 0xB1000 // #define OTA_ADDR 0x000B1000 in main.c
|
||||
#endif
|
||||
|
||||
2. load (B) to address 0x91000 // #define RAM_ALL_ADDR 0x00091000 in main.c
|
||||
|
||||
3. Download (A) to host as usual method.
|
||||
|
||||
|
||||
connect Ameba A and B as given
|
||||
|
||||
A: B:
|
||||
|
||||
SCK --- SPI_CLK
|
||||
CS --- SPI_CS
|
||||
MOSI--- SPI_OUT
|
||||
MISO--- SPI_IN
|
||||
INT --- SPI_INT
|
||||
|
||||
V3.3--- V3.3
|
||||
GND --- GND
|
||||
|
||||
Behavior:
|
||||
1. Slave end boot from SDIO, waiting master end download firmware (ram_all.bin + ota.bin or ota.e.bin)
|
||||
2. Master end download firmware to slave end, and wait slave firmware ready
|
||||
3. Master begin to do loopback test.
|
||||
270
project/realtek_ameba1_va0_example/example_sources/gspi_fw_loader/src/main.c
Executable file
270
project/realtek_ameba1_va0_example/example_sources/gspi_fw_loader/src/main.c
Executable file
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* 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 "rtl8195a.h"
|
||||
#include "build_info.h"
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
#include "hal_crypto.h"
|
||||
|
||||
/* debug message */
|
||||
#define FW_DL_DEBUG 0
|
||||
|
||||
#if FW_DL_DEBUG
|
||||
#define FW_INFO(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#define FW_ERR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#else
|
||||
#define FW_INFO(fmt, args...)
|
||||
#define FW_ERR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args)
|
||||
#endif
|
||||
|
||||
/* compulsive: define fw_loader start address on SRAM
|
||||
* One can adjust the address to avoid image overlap
|
||||
*/
|
||||
#define __ICFEDIT_region_BD_RAM_start__ 0x10060000
|
||||
|
||||
|
||||
// GPSI slave configuration
|
||||
#define OTA_INFO_region 0x1006FFC0
|
||||
#define DECIPHER_BLOCK_SIZE (16*1000) //define deciphering block size, must be multiple of 16
|
||||
// should not over 16000 = 16*1000
|
||||
|
||||
/* decryption buffer */
|
||||
u8 cache_buf[DECIPHER_BLOCK_SIZE+4];
|
||||
u8 key_buf[16+4]; // for Crypto engine alignment
|
||||
u8 iv_buf[16+4];
|
||||
u8 iv_tmp[16];
|
||||
|
||||
|
||||
static const u8 aes_cbc_slave_key[16] =
|
||||
{
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
|
||||
} ;
|
||||
|
||||
u8 aes_cbc_slave_iv[16] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
|
||||
// This structure must be cared byte-ordering
|
||||
//
|
||||
typedef struct _OTA_INFO
|
||||
{
|
||||
u32 crypto_type; // encyption type
|
||||
u8 info[32]; // encyption infomation (eg. aes_key)
|
||||
u32 size;
|
||||
u32 startaddr;
|
||||
}OTA_INFO, *POTA_INFO;
|
||||
|
||||
int aes_cbc_decryption(u8* aes_key,
|
||||
u8 aes_key_len,
|
||||
u8* aes_iv,
|
||||
u8 aes_iv_len,
|
||||
const u8 *input,
|
||||
u8 *output,
|
||||
u32 act_len)
|
||||
{
|
||||
u8 *key_buf_aligned;
|
||||
u8 *iv_buf_aligned;
|
||||
u8 *output_buf, *output_buf_aligned;
|
||||
int result = 0;
|
||||
u32 cipher_len = 0;
|
||||
|
||||
if(act_len%16)
|
||||
cipher_len = act_len + (16-act_len%16);
|
||||
else
|
||||
cipher_len = act_len;
|
||||
|
||||
if(cipher_len%16)
|
||||
return -1;
|
||||
|
||||
if(cipher_len > 0){
|
||||
key_buf_aligned = (u8 *) (((u32) key_buf + 4) / 4 * 4);
|
||||
iv_buf_aligned = (u8 *) (((u32) iv_buf + 4) / 4 * 4);
|
||||
output_buf = cache_buf;
|
||||
|
||||
if(output_buf == NULL){
|
||||
FW_ERR("Not enough space for cipher text.\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
output_buf_aligned = (u8 *) (((u32) output_buf + 4) / 4 * 4);
|
||||
memcpy(iv_buf_aligned, aes_iv, aes_iv_len);
|
||||
memset(output_buf_aligned, 0, cipher_len);
|
||||
|
||||
memcpy(key_buf_aligned, aes_key, aes_key_len);
|
||||
|
||||
result = rtl_crypto_aes_cbc_init(key_buf_aligned, aes_key_len);
|
||||
if(result == 0){
|
||||
memcpy(iv_tmp, (input + cipher_len - aes_iv_len), aes_iv_len);
|
||||
result = rtl_crypto_aes_cbc_decrypt(input, cipher_len, iv_buf_aligned, aes_iv_len, output_buf_aligned);
|
||||
if(result == 0){
|
||||
memcpy(aes_iv, iv_tmp, aes_iv_len);
|
||||
memcpy(output, output_buf_aligned, act_len);
|
||||
}else{
|
||||
FW_ERR("[%s]rtl_crypto_aes_cbc_decrypt fail.(status = %d)\n",__FUNCTION__,result);
|
||||
}
|
||||
}
|
||||
else{
|
||||
FW_ERR("[s%]rtl_crypto_aes_cbc_init fail.(status = %d)\n",__FUNCTION__,result);
|
||||
}
|
||||
}
|
||||
|
||||
if(result == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// GPSI fw loader
|
||||
void fw_loader(void){
|
||||
u8* pbuf = (u8*)OTA_INFO_region;
|
||||
u8 local_key[16];
|
||||
u8 remote_key[16]; // key from host
|
||||
u8 local_iv[16];
|
||||
u8 remote_iv[16]; // iv from host
|
||||
|
||||
u8 aes_key[16];
|
||||
u8 aes_iv[16];
|
||||
|
||||
POTA_INFO ota_info = NULL;
|
||||
u32 OTA_LoadAddr = 0;
|
||||
u32 OTA_Len = 0;
|
||||
u32 OTA_crypt = 0;
|
||||
|
||||
|
||||
u8* otg_img = NULL;
|
||||
u8* __ota_entry_func__ = NULL;
|
||||
u8* __ota_validate_code__ = NULL;
|
||||
|
||||
u32 ciphered_block_num = 0;
|
||||
u32 ciphered_remain = 0;
|
||||
|
||||
FW_INFO("===== Enter FW Loader Image ====\n");
|
||||
|
||||
ota_info = (POTA_INFO)pbuf;
|
||||
|
||||
/* local_key should be read from efuse */
|
||||
memcpy(local_key, aes_cbc_slave_key, sizeof(aes_cbc_slave_key));
|
||||
memcpy(local_iv, aes_cbc_slave_iv, sizeof(aes_cbc_slave_iv));
|
||||
|
||||
/* Load OTA info from cache */
|
||||
OTA_crypt = ota_info->crypto_type;
|
||||
OTA_Len = ota_info->size;
|
||||
OTA_LoadAddr= ota_info->startaddr;
|
||||
|
||||
__ota_entry_func__ = (u8*)OTA_LoadAddr;
|
||||
__ota_validate_code__ = __ota_entry_func__ + 4;
|
||||
otg_img = __ota_entry_func__; // ota ciphertext start address
|
||||
|
||||
if(!__ota_entry_func__){
|
||||
while (1) {
|
||||
FW_ERR(" Wrong ota entry pointer ...\n");
|
||||
RtlConsolRom(10000);
|
||||
}
|
||||
}
|
||||
|
||||
switch(OTA_crypt){
|
||||
case 0:
|
||||
FW_INFO("OTA encrytion: NONE\n");
|
||||
break;
|
||||
case 1:
|
||||
FW_INFO("OTA encrytion: AES_128_CBC\n");
|
||||
memcpy(remote_key, &(ota_info->info[0]), 16);
|
||||
memcpy(remote_iv, &(ota_info->info[16]), 16);
|
||||
|
||||
/* generate deciphering key and iv */
|
||||
for(int i=0;i<sizeof(aes_key);i++){
|
||||
aes_key[i] = local_key[i]^remote_key[i];
|
||||
}
|
||||
|
||||
memcpy(aes_iv, local_iv, sizeof(local_iv));
|
||||
|
||||
if(OTA_LoadAddr != 0){
|
||||
int index;
|
||||
int offset;
|
||||
int result;
|
||||
/* OTA decryption */
|
||||
ciphered_block_num = OTA_Len/DECIPHER_BLOCK_SIZE;
|
||||
ciphered_remain = OTA_Len%DECIPHER_BLOCK_SIZE;
|
||||
|
||||
FW_INFO("Deciphering Start ...\n");
|
||||
if ( rtl_cryptoEngine_init() != 0 ) {
|
||||
while (1) {
|
||||
FW_ERR("cryptoEngine init Fail ...\n");
|
||||
RtlConsolRom(10000);
|
||||
}
|
||||
}
|
||||
|
||||
for(index =0;index<ciphered_block_num;index++){
|
||||
offset = index*DECIPHER_BLOCK_SIZE;
|
||||
result = aes_cbc_decryption(aes_key, 16,aes_iv, 16, otg_img+offset, otg_img+offset, DECIPHER_BLOCK_SIZE);
|
||||
if(result != 0){
|
||||
FW_ERR("Deciphering OTA block (index=%d,length=%d) Fail\n",index, DECIPHER_BLOCK_SIZE);
|
||||
while (1) {
|
||||
FW_ERR("Deciphering fail...\n");
|
||||
RtlConsolRom(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ciphered_remain){
|
||||
offset = index*DECIPHER_BLOCK_SIZE;
|
||||
|
||||
result = aes_cbc_decryption(aes_key, 16, aes_iv, 16, otg_img+offset, otg_img+offset, ciphered_remain);
|
||||
if(result != 0){
|
||||
FW_ERR("Deciphering OTA remain(length=%d) Fail\n", ciphered_remain);
|
||||
while (1) {
|
||||
FW_ERR("Deciphering fail...\n");
|
||||
RtlConsolRom(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
FW_INFO("OTA deciphering DONE.\n");
|
||||
break;
|
||||
/* other encrytion method */
|
||||
default:
|
||||
FW_ERR("OTA encrytion: UNKOWN\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FW_INFO("===== Enter OTA Image ====\n");
|
||||
|
||||
PRAM_START_FUNCTION OTAEntryFun=(PRAM_START_FUNCTION)__ota_entry_func__;
|
||||
|
||||
// Unregister irq handler that has been registered in InfraStart() of fwloader.
|
||||
// These irq handler will be properly registered in InfraStart() of user's image2
|
||||
IRQ_HANDLE SysHandle;
|
||||
SysHandle.IrqNum = SYSTEM_ON_IRQ;
|
||||
InterruptUnRegister(&SysHandle);
|
||||
|
||||
//3 Jump to OTA Image
|
||||
FW_INFO("InfraStart: %p, Img2 Sign %s \n", OTAEntryFun, (char*)__ota_validate_code__);
|
||||
if (_strcmp((char *)__ota_validate_code__, "RTKWin")) {
|
||||
while (1) {
|
||||
FW_ERR("Invalid Image2 Signature\n");
|
||||
RtlConsolRom(10000);
|
||||
}
|
||||
}
|
||||
|
||||
OTAEntryFun->RamStartFun();
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
//2 Firmware Loader
|
||||
fw_loader();
|
||||
while(1);
|
||||
}
|
||||
|
||||
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 TIMER4
|
||||
|
||||
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 PD_4
|
||||
#define MBED_I2C_MTR_SCL PD_5
|
||||
|
||||
#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");
|
||||
RtlMsleepOS(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);
|
||||
|
||||
RtlMsleepOS(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.
|
||||
|
||||
98
project/realtek_ameba1_va0_example/example_sources/i2c/src/main.c
Executable file
98
project/realtek_ameba1_va0_example/example_sources/i2c/src/main.c
Executable file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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_MASTER_DEVICE
|
||||
#define I2C_SLAVE_DEVICE
|
||||
|
||||
#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_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
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
15
project/realtek_ameba1_va0_example/example_sources/i2c_dual/readme.txt
Executable file
15
project/realtek_ameba1_va0_example/example_sources/i2c_dual/readme.txt
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
Example Description
|
||||
|
||||
This example describes how to use i2c by using mbed api
|
||||
|
||||
1.Connect LOG-UART connector to PC
|
||||
|
||||
2.Connect board 1 and board 2
|
||||
board 1 board 2
|
||||
- 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.
|
||||
|
||||
327
project/realtek_ameba1_va0_example/example_sources/i2c_dual/src/main.c
Executable file
327
project/realtek_ameba1_va0_example/example_sources/i2c_dual/src/main.c
Executable file
|
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* 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 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 127
|
||||
char i2cdatasrc[I2C_DATA_LENGTH];
|
||||
char i2cdatadst[I2C_DATA_LENGTH];
|
||||
char i2cdatardsrc[I2C_DATA_LENGTH];
|
||||
char i2cdatarddst[I2C_DATA_LENGTH];
|
||||
|
||||
#define I2C_MASTER_DEVICE
|
||||
#ifndef I2C_MASTER_DEVICE
|
||||
#define I2C_SLAVE_DEVICE
|
||||
#endif
|
||||
|
||||
// RESTART verification
|
||||
#undef I2C_RESTART_DEMO
|
||||
|
||||
// Slave
|
||||
// RX
|
||||
#define CLEAR_SLV_RXC_FLAG (slaveRXC = 0)
|
||||
#define SET_SLV_RXC_FLAG (slaveRXC = 1)
|
||||
#define WAIT_SLV_RXC while(slaveRXC == 0){;}
|
||||
// Tx
|
||||
#define CLEAR_SLV_TXC_FLAG (slaveTXC = 0)
|
||||
#define SET_SLV_TXC_FLAG (slaveTXC = 1)
|
||||
#define WAIT_SLV_TXC while(slaveTXC == 0){;}
|
||||
// Read Request
|
||||
#define CLEAR_SLV_RD_REQ_FLAG (slaveRdReq = 0)
|
||||
#define SET_SLV_RD_REQ_FLAG (slaveRdReq = 1)
|
||||
#define WAIT_SLV_RD_REQ while(slaveRdReq == 0){;}
|
||||
|
||||
// Master
|
||||
// Rx
|
||||
#define CLEAR_MST_RXC_FLAG (masterRXC = 0)
|
||||
#define SET_MST_RXC_FLAG (masterRXC = 1)
|
||||
#define WAIT_MST_RXC while(masterRXC == 0){;}
|
||||
// Tx
|
||||
#define CLEAR_MST_TXC_FLAG (masterTXC = 0)
|
||||
#define SET_MST_TXC_FLAG (masterTXC = 1)
|
||||
#define WAIT_MST_TXC while(masterTXC == 0){;}
|
||||
|
||||
#if defined (__ICCARM__)
|
||||
i2c_t i2cmaster;
|
||||
i2c_t i2cslave;
|
||||
#else
|
||||
volatile i2c_t i2cmaster;
|
||||
volatile i2c_t i2cslave;
|
||||
#endif
|
||||
volatile int masterTXC;
|
||||
volatile int masterRXC;
|
||||
volatile int slaveTXC;
|
||||
volatile int slaveRXC;
|
||||
volatile int slaveRdReq;
|
||||
|
||||
void i2c_slave_rxc_callback(void *userdata)
|
||||
{
|
||||
|
||||
int i2clocalcnt;
|
||||
int result = 0;
|
||||
|
||||
i2c_enable_control(&i2cslave, 0);
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
|
||||
// DBG_8195A("i2c data: %02x \t %02x\n",i2cdatadst[i2clocalcnt],i2cdatadst[i2clocalcnt+1]);
|
||||
}
|
||||
//HalDelayUs(5000);
|
||||
|
||||
// verify result
|
||||
result = 1;
|
||||
#if !defined(I2C_RESTART_DEMO)
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) {
|
||||
if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt]) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (i2cdatasrc[0] == i2cdatadst[0]) {
|
||||
if (i2cdatasrc[0] != i2cdatadst[0]) {
|
||||
result = 0;
|
||||
}
|
||||
} else if (i2cdatasrc[1] == i2cdatadst[0]) {
|
||||
for (i2clocalcnt = 1; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) {
|
||||
if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt -1]) {
|
||||
DBG_8195A("idx:%d, src:%x, dst:%x\n", i2clocalcnt, i2cdatasrc[i2clocalcnt], i2cdatadst[i2clocalcnt]);
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
|
||||
DBG_8195A("i2c data: %02x \t %02x\n",i2cdatadst[i2clocalcnt],i2cdatadst[i2clocalcnt+1]);
|
||||
}
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) {
|
||||
if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt]) {
|
||||
DBG_8195A("idx:%d, src:%x, dst:%x\n", i2clocalcnt, i2cdatasrc[i2clocalcnt], i2cdatadst[i2clocalcnt]);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DBG_8195A("\r\nSlave receive: Result is %s\r\n", (result) ? "success" : "fail");
|
||||
_memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH);
|
||||
SET_SLV_RXC_FLAG;
|
||||
i2c_enable_control(&i2cslave, 1);
|
||||
}
|
||||
|
||||
|
||||
void i2c_master_rxc_callback(void *userdata)
|
||||
{
|
||||
|
||||
int i2clocalcnt;
|
||||
int result = 0;
|
||||
|
||||
//DBG_8195A("show master received data>>>\n");
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
|
||||
//DBG_8195A("i2c data: %02x \t %02x\n",i2cdatarddst[i2clocalcnt],i2cdatarddst[i2clocalcnt+1]);
|
||||
}
|
||||
|
||||
// verify result
|
||||
result = 1;
|
||||
for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) {
|
||||
if (i2cdatarddst[i2clocalcnt] != i2cdatardsrc[i2clocalcnt]) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG_8195A("\r\nMaster receive: Result is %s\r\n", (result) ? "success" : "fail");
|
||||
|
||||
}
|
||||
|
||||
void i2c_slave_txc_callback(void *userdata)
|
||||
{
|
||||
SET_SLV_TXC_FLAG;
|
||||
}
|
||||
|
||||
void i2c_master_txc_callback(void *userdata)
|
||||
{
|
||||
SET_MST_TXC_FLAG;
|
||||
}
|
||||
|
||||
void i2c_master_err_callback(void *userdata)
|
||||
{
|
||||
DBG_8195A("ERR:%x\n", i2cmaster.SalI2CHndPriv.SalI2CHndPriv.ErrType);
|
||||
}
|
||||
|
||||
void i2c_slave_rd_req_callback(void *userdata) {
|
||||
DBG_8195A("rd req\n");
|
||||
SET_SLV_RD_REQ_FLAG;
|
||||
}
|
||||
|
||||
void demo_i2c_master_enable(void)
|
||||
{
|
||||
_memset(&i2cmaster, 0x00, sizeof(i2c_t));
|
||||
i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
|
||||
i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK);
|
||||
i2c_set_user_callback(&i2cmaster, I2C_RX_COMPLETE, i2c_master_rxc_callback);
|
||||
i2c_set_user_callback(&i2cmaster, I2C_TX_COMPLETE, i2c_master_txc_callback);
|
||||
i2c_set_user_callback(&i2cmaster, I2C_ERR_OCCURRED, i2c_master_err_callback);
|
||||
#ifdef I2C_RESTART_DEMO
|
||||
i2c_restart_enable(&i2cmaster);
|
||||
#endif
|
||||
}
|
||||
|
||||
void demo_i2c_slave_enable(void)
|
||||
{
|
||||
_memset(&i2cslave, 0x00, sizeof(i2c_t));
|
||||
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_slave_rxc_callback);
|
||||
i2c_set_user_callback(&i2cslave, I2C_TX_COMPLETE, i2c_slave_txc_callback);
|
||||
i2c_set_user_callback(&i2cslave, I2C_RD_REQ_COMMAND, i2c_slave_rd_req_callback);
|
||||
}
|
||||
|
||||
void demo_i2c_master_write_1byte(void)
|
||||
{
|
||||
DBG_8195A("Mst-W\n");
|
||||
CLEAR_MST_TXC_FLAG;
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 0);
|
||||
WAIT_MST_TXC;
|
||||
DBG_8195A("Mst-W is complete and STOP bit is NOT sent.\n");
|
||||
}
|
||||
|
||||
void demo_i2c_master_write_n_1byte(void)
|
||||
{
|
||||
DBG_8195A("Mst-W\n");
|
||||
CLEAR_MST_TXC_FLAG;
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], (I2C_DATA_LENGTH-1), 1);
|
||||
//wait for master TXC
|
||||
WAIT_MST_TXC;
|
||||
}
|
||||
|
||||
void demo_i2c_master_write(void)
|
||||
{
|
||||
DBG_8195A("Mst-W\n");
|
||||
CLEAR_MST_TXC_FLAG;
|
||||
i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], I2C_DATA_LENGTH, 1);
|
||||
//wait for master TXC
|
||||
WAIT_MST_TXC;
|
||||
}
|
||||
|
||||
void demo_i2c_master_read(void)
|
||||
{
|
||||
DBG_8195A("Mst-R\n");
|
||||
DBG_8195A("Mst-R need to wait Slv-W complete.\n");
|
||||
CLEAR_MST_RXC_FLAG;
|
||||
i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatarddst[0], I2C_DATA_LENGTH, 1);
|
||||
WAIT_MST_RXC;
|
||||
}
|
||||
|
||||
void demo_i2c_slave_read(void)
|
||||
{
|
||||
DBG_8195A("Slv-R\n");
|
||||
CLEAR_SLV_RXC_FLAG;
|
||||
i2c_slave_read(&i2cslave, &i2cdatadst[0], I2C_DATA_LENGTH);
|
||||
WAIT_SLV_RXC;
|
||||
}
|
||||
|
||||
void demo_i2c_slave_read_1byte(void)
|
||||
{
|
||||
DBG_8195A("Slv-R\n");
|
||||
CLEAR_SLV_RXC_FLAG;
|
||||
i2c_slave_read(&i2cslave, &i2cdatadst[0], 1);
|
||||
WAIT_SLV_RXC;
|
||||
}
|
||||
|
||||
void demo_i2c_slave_write(void)
|
||||
{
|
||||
DBG_8195A("Slv-W\n");
|
||||
CLEAR_SLV_RD_REQ_FLAG;
|
||||
i2c_slave_set_for_rd_req(&i2cslave, 1);
|
||||
WAIT_SLV_RD_REQ;
|
||||
CLEAR_SLV_TXC_FLAG;
|
||||
i2c_slave_write(&i2cslave, &i2cdatardsrc[0], I2C_DATA_LENGTH);
|
||||
WAIT_SLV_TXC;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i2clocalcnt;
|
||||
|
||||
DBG_8195A("Slave address: 0x%x\n", MBED_I2C_SLAVE_ADDR0);
|
||||
#ifdef I2C_RESTART_DEMO
|
||||
DBG_8195A("Enable restart\n");
|
||||
#endif
|
||||
|
||||
// prepare for transmission
|
||||
_memset(&i2cdatasrc[0], 0x00, I2C_DATA_LENGTH);
|
||||
_memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH);
|
||||
_memset(&i2cdatardsrc[0], 0x00, I2C_DATA_LENGTH);
|
||||
_memset(&i2cdatarddst[0], 0x00, I2C_DATA_LENGTH);
|
||||
|
||||
for (i2clocalcnt=0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++){
|
||||
i2cdatasrc[i2clocalcnt] = i2clocalcnt+0x2;
|
||||
}
|
||||
|
||||
for (i2clocalcnt=0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++){
|
||||
i2cdatardsrc[i2clocalcnt] = i2clocalcnt+1;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
|
||||
// ------- Dual board -------
|
||||
#ifdef I2C_MASTER_DEVICE
|
||||
demo_i2c_master_enable();
|
||||
|
||||
// Master write - Slave read
|
||||
#ifdef I2C_RESTART_DEMO
|
||||
demo_i2c_master_write_1byte();
|
||||
demo_i2c_master_write_n_1byte(); // n-1 bytes
|
||||
#else
|
||||
demo_i2c_master_write();
|
||||
#endif
|
||||
|
||||
// Master read - Slave write
|
||||
#ifdef I2C_RESTART_DEMO
|
||||
demo_i2c_master_write_1byte();
|
||||
#endif
|
||||
demo_i2c_master_read();
|
||||
#endif // #ifdef I2C_MASTER_DEVICE
|
||||
|
||||
|
||||
#ifdef I2C_SLAVE_DEVICE
|
||||
demo_i2c_slave_enable();
|
||||
i2c_slave_set_for_data_nak(&i2cslave, 1);
|
||||
HalDelayUs(5000);
|
||||
i2c_slave_set_for_data_nak(&i2cslave, 0);
|
||||
// Master write - Slave read
|
||||
demo_i2c_slave_read();
|
||||
|
||||
// Master read - Slave write
|
||||
#ifdef I2C_RESTART_DEMO
|
||||
demo_i2c_slave_read_1byte();
|
||||
#endif
|
||||
demo_i2c_slave_write();
|
||||
#endif // #ifdef I2C_SLAVE_DEVICE
|
||||
|
||||
while(1){;}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
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
331
project/realtek_ameba1_va0_example/example_sources/i2s/src/main.c
Executable file
331
project/realtek_ameba1_va0_example/example_sources/i2s/src/main.c
Executable file
|
|
@ -0,0 +1,331 @@
|
|||
#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.h"
|
||||
/*
|
||||
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==14700
|
||||
#if SAMPLE_FILE_CHNUM==2
|
||||
#include "birds_14700_2ch_16b.c"
|
||||
#undef SAMPLE_FILE_RATE
|
||||
#define SAMPLE_FILE_RATE SR_14p7KHZ
|
||||
#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_14p7KHZ,
|
||||
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){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Example Description
|
||||
|
||||
Using the ALC5680 extension board to recognize keyword.
|
||||
The dafault keyword is hello bluegenie.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 ALC5680 shield to Ameba HDK
|
||||
|
||||
2.Run the main function.
|
||||
|
||||
3.Plug earphone or speaker to phone jack
|
||||
|
||||
4.Say the keyword then the light will light.
|
||||
|
||||
The gpio pin definition as below:
|
||||
|
||||
Voice trigger interrupt : PC_5
|
||||
Led control pin : PE_5
|
||||
I2S SCLK PIN : PC_1
|
||||
I2S WS PIN : PC_0
|
||||
I2S SD PIN : PE_5
|
||||
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/* This is software bypass example */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include "timer_api.h"
|
||||
#include "i2s_api.h"
|
||||
#include "alc5680.h"
|
||||
#include <platform_stdlib.h>
|
||||
|
||||
|
||||
#define LOOP_BACK
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
#include "gpio_api.h" // mbed
|
||||
#include "gpio_irq_api.h" // mbed
|
||||
#define GPIO_IRQ_PIN PC_5
|
||||
|
||||
static i2s_t i2s_obj;
|
||||
|
||||
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
|
||||
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
|
||||
|
||||
static u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
|
||||
static 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
|
||||
|
||||
#define GPIO_LED_PIN PE_5
|
||||
|
||||
static unsigned char voice_irq = 0;
|
||||
static gpio_t gpio_led;
|
||||
|
||||
#define led_off 1
|
||||
#define led_on 0
|
||||
|
||||
#define LED_TIME_PERIOD 100000 //100MS
|
||||
|
||||
static void voice_triger_timer_handler(uint32_t id)
|
||||
{
|
||||
static unsigned int count = 0;
|
||||
if(voice_irq){
|
||||
if(count == 2){
|
||||
gpio_write(&gpio_led, led_off);
|
||||
count = 0;
|
||||
voice_irq = 0;
|
||||
}else{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void voice_demo_irq_handler (uint32_t id, gpio_irq_event event)
|
||||
{
|
||||
if(voice_irq == 0){
|
||||
gpio_write(&gpio_led, led_on);
|
||||
printf("voice irq \r\n");
|
||||
voice_irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void test_tx_complete(void *data, char *pbuf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static 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);
|
||||
#ifdef LOOP_BACK
|
||||
_memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE);
|
||||
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
|
||||
#endif
|
||||
i2s_recv_page(obj); // submit a new page for receive
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gtimer_t voice_triger_timer;
|
||||
gpio_irq_t voice_irq;
|
||||
gpio_t voice_pinr;
|
||||
|
||||
printf("GPIO_INIT\r\n");
|
||||
// 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
|
||||
gpio_write(&gpio_led, led_off);
|
||||
|
||||
// Initial Push Button pin as interrupt source
|
||||
gpio_irq_init(&voice_irq, GPIO_IRQ_PIN, voice_demo_irq_handler, (uint32_t)(&voice_pinr));
|
||||
gpio_irq_set(&voice_irq, IRQ_RISE, 1); // Rising Edge Trigger
|
||||
//gpio_mode(&voice_irq, PullUp); // Pull-High
|
||||
gpio_irq_enable(&voice_irq);
|
||||
|
||||
gtimer_init(&voice_triger_timer, TIMER0);
|
||||
gtimer_start_periodical(&voice_triger_timer, LED_TIME_PERIOD, (void*)voice_triger_timer_handler, NULL);
|
||||
|
||||
// I2S init
|
||||
|
||||
i2s_obj.sampling_rate = SR_48KHZ;
|
||||
i2s_obj.channel_num = I2S_CH_STEREO;
|
||||
i2s_obj.word_length = I2S_WL_16;
|
||||
|
||||
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);
|
||||
//show the voice trigger version
|
||||
alc5680_i2c_init();
|
||||
alc5680_get_version();
|
||||
|
||||
while(1){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
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
|
||||
|
||||
85
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/main.c
Executable file
85
project/realtek_ameba1_va0_example/example_sources/i2s_bypass/src/main.c
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
/* 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.h"
|
||||
|
||||
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){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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,99 @@
|
|||
/* 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.h"
|
||||
|
||||
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){
|
||||
asm volatile ("nop\n\t");//If run in non-os environment,it needs to add nop operation
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
asm volatile ("nop\n\t");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 "log_uart_api.h"
|
||||
|
||||
log_uart_t uobj;
|
||||
|
||||
void uart_send_string(log_uart_t *uobj, char *pstr)
|
||||
{
|
||||
unsigned int i=0;
|
||||
|
||||
while (*(pstr+i) != 0) {
|
||||
log_uart_putc(uobj, *(pstr+i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// sample text
|
||||
char rc;
|
||||
// Initial Log UART: BaudRate=115200, 8-bits, No Parity, 1 Stop bit
|
||||
log_uart_init(&uobj, 115200, 8, ParityNone, 1);
|
||||
|
||||
uart_send_string(&uobj, "UART API Demo...\r\n");
|
||||
uart_send_string(&uobj, "Hello World!!\r\n");
|
||||
while(1){
|
||||
uart_send_string(&uobj, "\r\n8195a$");
|
||||
rc = log_uart_getc(&uobj);
|
||||
log_uart_putc(&uobj, rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 "log_uart_api.h"
|
||||
|
||||
char buf[100]="Hello World!!\r\n";;
|
||||
log_uart_t uobj;
|
||||
|
||||
int uart_scan (char *buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<100;i++) {
|
||||
*(buf+i) = log_uart_getc(&uobj);
|
||||
if ((*(buf+i) == 0x0A) || (*(buf+i) == 0x0D)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
log_uart_init(&uobj, 38400, 8, ParityNone, 1);
|
||||
log_uart_send(&uobj, buf, _strlen(buf), 100);
|
||||
|
||||
while (1) {
|
||||
// ret = log_uart_recv(&uobj, buf, 100, 2000);
|
||||
ret = uart_scan(buf);
|
||||
log_uart_send(&uobj, buf, ret, 1000);
|
||||
log_uart_putc(&uobj, 0x0A);
|
||||
log_uart_putc(&uobj, 0x0D);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 "log_uart_api.h"
|
||||
|
||||
#define BUF_SZ (1024*3)
|
||||
|
||||
extern void wait_ms(int ms);
|
||||
|
||||
char buf[BUF_SZ]="Hello World!!\r\n";;
|
||||
volatile uint32_t tx_busy=0;
|
||||
volatile uint32_t rx_busy=0;
|
||||
log_uart_t uobj;
|
||||
|
||||
void uart_tx_done(uint32_t id)
|
||||
{
|
||||
log_uart_t *uobj = (void*)id;
|
||||
tx_busy = 0;
|
||||
}
|
||||
|
||||
void uart_rx_done(uint32_t id)
|
||||
{
|
||||
log_uart_t *uobj = (void*)id;
|
||||
rx_busy = 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
int timeout;
|
||||
|
||||
log_uart_init(&uobj, 38400, 8, ParityNone, 1);
|
||||
|
||||
log_uart_tx_comp_handler(&uobj, (void*)uart_tx_done, (uint32_t) &uobj);
|
||||
log_uart_rx_comp_handler(&uobj, (void*)uart_rx_done, (uint32_t) &uobj);
|
||||
|
||||
log_uart_send(&uobj, buf, _strlen(buf), 100);
|
||||
|
||||
while (1) {
|
||||
rx_busy = 1;
|
||||
log_uart_recv_stream(&uobj, buf, BUF_SZ);
|
||||
timeout = 2000;
|
||||
ret = BUF_SZ;
|
||||
while (rx_busy) {
|
||||
wait_ms(1);
|
||||
timeout--;
|
||||
if (timeout == 0) {
|
||||
// return value is the bytes received
|
||||
ret = log_uart_recv_stream_abort(&uobj);
|
||||
rx_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
buf[ret] = 0; // end of string
|
||||
tx_busy = 1;
|
||||
log_uart_send_stream(&uobj, buf, ret);
|
||||
timeout = 2000;
|
||||
while (tx_busy) {
|
||||
wait_ms(1);
|
||||
timeout--;
|
||||
if (timeout == 0) {
|
||||
tx_busy = 0;
|
||||
// return value is the bytes transmitted
|
||||
ret = log_uart_send_stream_abort(&uobj);
|
||||
}
|
||||
}
|
||||
log_uart_putc(&uobj, 0x0d);
|
||||
log_uart_putc(&uobj, 0x0a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
220
project/realtek_ameba1_va0_example/example_sources/nfc/src/main.c
Executable file
220
project/realtek_ameba1_va0_example/example_sources/nfc/src/main.c
Executable file
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* 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() {
|
||||
int i, address;
|
||||
int modified_page_count;
|
||||
|
||||
// dump the modified tag content
|
||||
modified_page_count = 0;
|
||||
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]);
|
||||
}
|
||||
|
||||
// update to cache from page 4
|
||||
nfc_cache_write(&nfctag, &(nfc_tag_content[4]), 4, modified_page_count);
|
||||
|
||||
modified_page_count += 4; // we also need update tag header to flash which has size 4
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
22
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/readme.txt
Executable file
22
project/realtek_ameba1_va0_example/example_sources/pm_deepsleep/readme.txt
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
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.
|
||||
|
||||
NOTE: You will see device resume immediately at first time.
|
||||
It's because the log uart is a wakeup source and it buffered a wakeup event when DAP is used.
|
||||
The symptom won't appear if you use power source on R43 and only power on module.
|
||||
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.
|
||||
105
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/src/main.c
Executable file
105
project/realtek_ameba1_va0_example/example_sources/pm_deepstandby/src/main.c
Executable file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
DiagPrintf("Sleep 8s... (Or wakeup by pushing button)\r\n");
|
||||
//turn off log uart to avoid warning in gpio_pull_control()
|
||||
sys_log_uart_off();
|
||||
// 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();
|
||||
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.
|
||||
86
project/realtek_ameba1_va0_example/example_sources/pm_sleep/src/main.c
Executable file
86
project/realtek_ameba1_va0_example/example_sources/pm_sleep/src/main.c
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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;
|
||||
int IsDramOn = 1;
|
||||
|
||||
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");
|
||||
//system will hang when it tries to suspend SDRAM for 8711AF
|
||||
if ( sys_is_sdram_power_on() == 0 ) {
|
||||
IsDramOn = 0;
|
||||
}
|
||||
|
||||
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_selective(SLP_GPIO | SLEEP_WAKEUP_BY_STIMER, 8000, 0, IsDramOn); // 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.
|
||||
167
project/realtek_ameba1_va0_example/example_sources/pm_tickless/src/main.c
Executable file
167
project/realtek_ameba1_va0_example/example_sources/pm_tickless/src/main.c
Executable file
|
|
@ -0,0 +1,167 @@
|
|||
#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 PMU_USER_DEVICE PMU_DEV_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) {
|
||||
pmu_acquire_wakelock(BIT(PMU_USER_DEVICE));
|
||||
|
||||
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;
|
||||
pmu_release_wakelock(BIT(PMU_USER_DEVICE));
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
pmu_acquire_wakelock(BIT(PMU_USER_DEVICE));
|
||||
}
|
||||
|
||||
void pre_sleep_process_callback(unsigned int expected_idle_time, void* param_ptr)
|
||||
{
|
||||
// For peripherals that need turned off before sleep, call disable or deinit peripheral here
|
||||
}
|
||||
|
||||
void post_sleep_process_callback(unsigned int expected_idle_time, void* param_ptr)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
/* PMU_LOGUART_DEVICE is also handled in log service.
|
||||
* It is release after a complete command is sent.
|
||||
**/
|
||||
pmu_acquire_wakelock(BIT(PMU_LOGUART_DEVICE));
|
||||
}
|
||||
|
||||
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 PMU_OS is locked.
|
||||
// Release this wakelock to enable tickless
|
||||
pmu_release_wakelock(BIT(PMU_OS));
|
||||
|
||||
// Register pre/post sleep callback. They are called when system automatically enter/leave sleep.
|
||||
pmu_register_sleep_callback(BIT(PMU_USER_DEVICE), pre_sleep_process_callback, NULL, post_sleep_process_callback, NULL);
|
||||
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
|
||||
38
project/realtek_ameba1_va0_example/example_sources/sdio_device/readme.txt
Executable file
38
project/realtek_ameba1_va0_example/example_sources/sdio_device/readme.txt
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
Example Description
|
||||
|
||||
This loopback example describes how to use Ameba SDIO device APIs in spdio_api.c and spdio_api.h.
|
||||
|
||||
How to build:
|
||||
1. copy src\main.c to project\realtek_ameba1_va0_example\src
|
||||
2. include lib\lib_sdiod.a for build, then re-build the project
|
||||
|
||||
Requirement Components:
|
||||
PC (running Linux kernel over 3.13) * 1
|
||||
Ameba EVB * 1
|
||||
|
||||
Pin assignment for SDIO device on Ameba EVB:
|
||||
--------------|----------------|-----------------------
|
||||
GPIO Pin name | SDIO pin name | Pin name on Ameba EVB 3V0
|
||||
--------------|----------------|-----------------------
|
||||
GPIOA4 | SD_D0 | D5
|
||||
-------------------------------------------------------
|
||||
GPIOA5 | SD_D1 | D2
|
||||
-------------------------------------------------------
|
||||
GPIOA0 | SD_D2 | D17
|
||||
-------------------------------------------------------
|
||||
GPIOA1 | SD_D3 | D16
|
||||
-------------------------------------------------------
|
||||
GPIOA2 | SD_CMD | D7
|
||||
-------------------------------------------------------
|
||||
GPIOA3 | SD_CLK | D6
|
||||
-------------------------------------------------------
|
||||
GND | GND | GND
|
||||
-------------------------------------------------------
|
||||
|
||||
Set-up:
|
||||
1. Connect Ameba to PC via SDIO slot
|
||||
2. build this example and upload firmware to Ameba EVB
|
||||
3. build iNIC host SDK and run loopback test (refer to Run Loopback test.docx in iNIC source)
|
||||
|
||||
Behaviour:
|
||||
PC sends loopback packet to Ameba and Ameba will send back to PC whatever received
|
||||
138
project/realtek_ameba1_va0_example/example_sources/sdio_device/src/main.c
Executable file
138
project/realtek_ameba1_va0_example/example_sources/sdio_device/src/main.c
Executable file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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 "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "main.h"
|
||||
#include "spdio_api.h"
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#define EX_SPDIO_STACKSIZE 2048
|
||||
#define EX_SPDIO_TX_BD_NUM 24 //n*2, 2 bd for one transaction
|
||||
#define EX_SPDIO_RX_BD_NUM 20
|
||||
#define EX_SPDIO_RX_BUFSZ (SPDIO_RX_BUFSZ_ALIGN(2048+24)) //n*64, must be rounded to 64, extra 24 bytes for spdio header info
|
||||
|
||||
struct spdio_t spdio_dev;
|
||||
|
||||
/*
|
||||
* param: pdata, package
|
||||
*/
|
||||
char ex_spdio_tx(u8 *pdata, u16 size, u8 type){
|
||||
static int loop_cnt = 0;
|
||||
struct spdio_buf_t *tx_buf = (struct spdio_buf_t *)malloc(sizeof(struct spdio_buf_t));
|
||||
memset((u8 *)tx_buf, 0, sizeof(struct spdio_buf_t));
|
||||
if(!tx_buf)
|
||||
return FAIL;
|
||||
tx_buf->buf_allocated = (u32)malloc(size + SPDIO_DMA_ALIGN_4);
|
||||
if(!tx_buf->buf_allocated)
|
||||
{
|
||||
free((u8 *)tx_buf);
|
||||
return FAIL;
|
||||
}
|
||||
tx_buf->size_allocated = size + SPDIO_DMA_ALIGN_4;
|
||||
|
||||
tx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(tx_buf->buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
|
||||
// copy data
|
||||
memcpy((void*)tx_buf->buf_addr, pdata, size);
|
||||
|
||||
tx_buf->buf_size = size;
|
||||
tx_buf->type = SPDIO_RX_DATA_USER; // you can define your own data type in spdio_rx_data_t and spdio_tx_data_t
|
||||
printf("loopback package, size = %d (cnt = %d) heap=%d\n", size, ++loop_cnt, xPortGetFreeHeapSize());
|
||||
// loopback
|
||||
spdio_tx(&spdio_dev, tx_buf);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*spdio rx done callback (HOST->Device), manage your package and buffer*/
|
||||
char ex_spdio_rx_done_cb(void *priv, void *pbuf, u8 *pdata, u16 size, u8 type){
|
||||
struct spdio_t *obj = (struct spdio_t *)priv;
|
||||
struct spdio_buf_t* rx_buf = (struct spdio_buf_t*)pbuf;
|
||||
|
||||
// handle package received
|
||||
ex_spdio_tx(pdata, size, type);
|
||||
|
||||
// manage rx_buf here
|
||||
free((char *)rx_buf->buf_allocated);
|
||||
|
||||
// assign new buffer for SPDIO RX
|
||||
rx_buf->buf_allocated = (u32)malloc(obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4);
|
||||
rx_buf->size_allocated = obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4;
|
||||
|
||||
// this buffer must be 4 byte alignment
|
||||
rx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(rx_buf->buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*spdio tx done callback(Device->HOST), manage buffer*/
|
||||
// this API will be called after package have been moved to HOST
|
||||
char ex_spdio_tx_done_cb(void *priv, void *pbuf){
|
||||
|
||||
struct spdio_buf_t* tx_buf = (struct spdio_buf_t*)pbuf;
|
||||
|
||||
free((u8 *)tx_buf->buf_allocated);
|
||||
free((u8 *)tx_buf);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ex_spdio_thread(void* param){
|
||||
|
||||
int i;
|
||||
|
||||
spdio_dev.priv = NULL;
|
||||
spdio_dev.rx_bd_num = EX_SPDIO_RX_BD_NUM;
|
||||
spdio_dev.tx_bd_num = EX_SPDIO_TX_BD_NUM;
|
||||
spdio_dev.rx_bd_bufsz = EX_SPDIO_RX_BUFSZ;
|
||||
|
||||
spdio_dev.rx_buf = (struct spdio_buf_t *)malloc(spdio_dev.rx_bd_num*sizeof(struct spdio_buf_t));
|
||||
if(!spdio_dev.rx_buf){
|
||||
printf("malloc failed for spdio buffer structure!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0;i<spdio_dev.rx_bd_num;i++){
|
||||
spdio_dev.rx_buf[i].buf_allocated = (u32)malloc(spdio_dev.rx_bd_bufsz + SPDIO_DMA_ALIGN_4);
|
||||
if(!spdio_dev.rx_buf[i].buf_allocated){
|
||||
printf("malloc failed for spdio buffer!\n");
|
||||
return;
|
||||
}
|
||||
spdio_dev.rx_buf[i].size_allocated = spdio_dev.rx_bd_bufsz + SPDIO_DMA_ALIGN_4;
|
||||
// this buffer must be 4 byte alignment
|
||||
spdio_dev.rx_buf[i].buf_addr = (u32)N_BYTE_ALIGMENT((u32)(spdio_dev.rx_buf[i].buf_allocated), SPDIO_DMA_ALIGN_4);
|
||||
}
|
||||
|
||||
spdio_dev.rx_done_cb = ex_spdio_rx_done_cb;
|
||||
spdio_dev.tx_done_cb = ex_spdio_tx_done_cb;
|
||||
|
||||
spdio_init(&spdio_dev);
|
||||
printf("SDIO device starts loopback!\n");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if(xTaskCreate(ex_spdio_thread, ((const char*)"ex_spdio_thread"), EX_SPDIO_STACKSIZE, NULL, tskIDLE_PRIORITY + 5, NULL) != pdPASS) {
|
||||
printf("xTaskCreate(ex_spdio_thread) failed\r\n");
|
||||
}
|
||||
|
||||
//3 3)Enable Schedule, Start Kernel
|
||||
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
|
||||
#ifdef PLATFORM_FREERTOS
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
#else
|
||||
RtlConsolTaskRom(NULL);
|
||||
#endif
|
||||
}
|
||||
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,25 @@
|
|||
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.
|
||||
To ensure the order is correct, we use a GPIO pin to notify the master that the slave device is ready to write or read data.
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* 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
|
||||
#define GPIO_SYNC_PIN PA_1
|
||||
|
||||
// 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 MasterTxDone;
|
||||
volatile int MasterRxDone;
|
||||
volatile int SlaveTxDone;
|
||||
volatile int SlaveRxDone;
|
||||
gpio_t GPIO_Syc;
|
||||
|
||||
void master_tr_done_callback(void *pdata, SpiIrq event)
|
||||
{
|
||||
switch(event){
|
||||
case SpiRxIrq:
|
||||
DBG_8195A("Master RX done!\n");
|
||||
MasterRxDone = 1;
|
||||
gpio_write(&GPIO_Syc, 0);
|
||||
break;
|
||||
case SpiTxIrq:
|
||||
DBG_8195A("Master TX done!\n");
|
||||
MasterTxDone = 1;
|
||||
break;
|
||||
default:
|
||||
DBG_8195A("unknown interrput evnent!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void slave_tr_done_callback(void *pdata, SpiIrq event)
|
||||
{
|
||||
switch(event){
|
||||
case SpiRxIrq:
|
||||
DBG_8195A("Slave RX done!\n");
|
||||
SlaveRxDone = 1;
|
||||
gpio_write(&GPIO_Syc, 0);
|
||||
break;
|
||||
case SpiTxIrq:
|
||||
DBG_8195A("Slave TX done!\n");
|
||||
SlaveTxDone = 1;
|
||||
break;
|
||||
default:
|
||||
DBG_8195A("unknown interrput evnent!\n");
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
gpio_init(&GPIO_Syc, GPIO_SYNC_PIN);
|
||||
gpio_write(&GPIO_Syc, 0);//Initialize GPIO Pin to low
|
||||
gpio_dir(&GPIO_Syc, PIN_OUTPUT); // Direction: Output
|
||||
gpio_mode(&GPIO_Syc, PullNone); // No pull
|
||||
|
||||
#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
|
||||
|
||||
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");
|
||||
MasterTxDone = 0;
|
||||
while(gpio_read(&GPIO_Syc) == 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(MasterTxDone == 0) {
|
||||
wait_ms(10);
|
||||
i++;
|
||||
}
|
||||
DBG_8195A("SPI Master Write Done!!\r\n");
|
||||
|
||||
DBG_8195A("SPI Master Read Test==>\r\n");
|
||||
|
||||
|
||||
_memset(TestBuf, 0, TEST_BUF_SIZE);
|
||||
spi_flush_rx_fifo(&spi_master);
|
||||
|
||||
MasterRxDone = 0;
|
||||
while(gpio_read(&GPIO_Syc) == 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(MasterRxDone == 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);
|
||||
SlaveRxDone = 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
|
||||
gpio_write(&GPIO_Syc, 1);
|
||||
i=0;
|
||||
DBG_8195A("SPI Slave Wait Read Done...\r\n");
|
||||
while(SlaveRxDone == 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");
|
||||
SlaveTxDone = 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
|
||||
gpio_write(&GPIO_Syc, 1);
|
||||
|
||||
i=0;
|
||||
DBG_8195A("SPI Slave Wait Write Done...\r\n");
|
||||
while(SlaveTxDone == 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Example Description
|
||||
|
||||
This example demo the function of Auto Flow control.
|
||||
Please connect 2 board to run this example.
|
||||
|
||||
|
||||
Required Components:
|
||||
2 EV boards
|
||||
|
||||
Connect to 2 borads
|
||||
|
||||
Board1 Board2
|
||||
PA6 <-----> PA7
|
||||
PA7 <-----> PA6
|
||||
PA5 <-----> PA3
|
||||
PA3 <-----> PA5
|
||||
GND <-----> GND
|
||||
|
||||
This example shows:
|
||||
The first powered board will be the TX side, the othse one will be the RX side.
|
||||
The RX side will make some delay every 16-bytes received, by this way we can trigger the flow control mechanism.
|
||||
|
||||
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