add examples

This commit is contained in:
pvvx 2016-12-14 04:21:37 +03:00
parent 265d41b6a3
commit 4128624f93
112 changed files with 158017 additions and 0 deletions

View file

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

View file

@ -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);
}

View file

@ -0,0 +1,7 @@
Example Description
This example describes how to use CRYPTO function, it is based on cutomer requirement modified.
use Arduino board to test, and it will show at console

View file

@ -0,0 +1,408 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "FreeRTOS.h"
#include "task.h"
#include "device.h"
#include "serial_api.h"
#include "hal_crypto.h"
#include "main.h"
#include "diag.h"
#include <polarssl/aes.h>
#define STACKSIZE 2048
//static const u8 plaintext[] = "The quick brown fox jumps over the lazy dog";
//static const u8 md5_digest[] = "\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
// "\x6b\xd8\x1d\x35\x42\xa4\x19\xd6";
//static const u8 md5_key[] = "key";
static const char plaintext[] = "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890";
static const char md5_digest[] = { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A };
static const u8 md5_key[] = "key";
static unsigned char md5_test_buf[16][128] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "The quick brown fox jumps over the lazy dog" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" },
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "The quick brown fox jumps over the lazy dog" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const int md5_test_buflen[16] =
{
0, 1, 3, 14, 26, 43, 62, 80, 0, 1, 3, 14, 26, 43, 62, 80
};
static const unsigned char md5_test_sum[16][16] =
{
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
{"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
"\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"},
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A },
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
{"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82"
"\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"},
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A },
};
u8 digest[64];
u8 cipher_result[2048];
u8 test_result[1024];
serial_t sobj;
/*
*
*
* This test_md5 function is used to test hardware md5 functoinality
*/
void test_md5(void)
{
int i;
int ret;
u8 md5sum[16];
DiagPrintf("MD5 test\r\n");
ret = rtl_crypto_md5(plaintext, strlen(plaintext), (unsigned char *)&digest); // the length of MD5's digest is 16 bytes.
if ( rtl_memcmpb(digest, md5_digest, 16) == 0 ) {
DiagPrintf("MD5 test result is correct, ret=%d\r\n", ret);
} else {
DiagPrintf("MD5 test result is WRONG!!, ret=%d\r\n", ret);
}
for( i = 0; i < 16; i++ )
{
DiagPrintf( " MD5 test #%d: ", i + 1 );
ret = rtl_crypto_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); // the length of MD5's digest is 16 bytes.
DiagPrintf(" MD5 ret=%d\n", ret);
if( rtl_memcmpb( md5sum, md5_test_sum[i], 16 ) != 0 )
{
DiagPrintf( "failed\n" );
memset(md5sum,0,16);
}
else{
DiagPrintf( "passed\n" );
memset(md5sum,0,16);}
}
}
//
// vector : AES CBC 128 bit :
// http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
//
//#ifdef __ICCARM__
//#pragma data_alignment = 4
//#elif defined (__GNUC__)
//__attribute__ ((aligned (4)))
//#endif
static const unsigned char aes_test_key[16] =
{
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
} ;
//#ifdef __ICCARM__
//#pragma data_alignment = 4
//#elif defined (__GNUC__)
//__attribute__ ((aligned (4)))
//#endif
static const unsigned char aes_test_iv_1[16] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};
static const unsigned char aes_test_buf[16] =
{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
static const unsigned char aes_test_ecb_buf[160] =
{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
};
static const unsigned char aes_test_res_128[16] =
{
0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d
};
static const unsigned char aes_test_ecb_res_128[160] =
{
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97
};
/*
*
* THis test_aes_cbc function is use to directly test hardware aes cbc crypto functionality
*
*/
int test_aes_cbc(void)
{
const u8 *key, *pIv;
u32 keylen= 0;
u32 ivlen = 0;
u8 *message;
u32 msglen;
u8 *pResult;
int ret;
DiagPrintf("AES CBC test\r\n");
key = aes_test_key;
keylen = 16;
pIv = aes_test_iv_1;
ivlen = 16;
pResult = cipher_result;
message = (unsigned char *)aes_test_buf;
msglen = sizeof(aes_test_buf);
ret = rtl_crypto_aes_cbc_init(key,keylen);
if ( ret != 0 ) {
DiagPrintf("AES CBC init failed\r\n");
return ret;
}
ret = rtl_crypto_aes_cbc_encrypt(message, msglen, pIv, ivlen, pResult);
if ( ret != 0 ) {
DiagPrintf("AES CBC encrypt failed\r\n");
return ret;
}
if ( rtl_memcmpb(aes_test_res_128, pResult, msglen) == 0 ) {
DiagPrintf("AES CBC encrypt result success\r\n");
} else {
DiagPrintf("AES CBC encrypt result failed\r\n");
}
message = pResult;
ret = rtl_crypto_aes_cbc_decrypt(message, msglen, pIv, ivlen, pResult);
if ( ret != 0 ) {
DiagPrintf("AES CBC decrypt failed, ret=%d\r\n", ret);
return ret;
}
if ( rtl_memcmpb(aes_test_buf, pResult, msglen) == 0 ) {
DiagPrintf("AES CBC decrypt result success\r\n");
} else {
DiagPrintf("AES CBC decrypt result failed\r\n");
}
return 0;
}
/*
*
* THis test_aes_ecb function is use to directly test hardware ecb cbc crypto functionality
*
* The input parameter for ecb need to confirm iv is null and ivlen is 0
*/
int test_aes_ecb(void)
{
const u8 *key, *pIv;
u32 keylen= 0;
u32 ivlen = 0;
u8 *message;
u32 msglen;
u8 *pResult;
int ret;
DiagPrintf("AES ECB test\r\n");
key = aes_test_key;
keylen = 16;
pIv = NULL;
ivlen = 0;
pResult = cipher_result;
message = (unsigned char *)aes_test_ecb_buf;
msglen = sizeof(aes_test_buf);
//for(int i=0;i<msglen;i++)
//printf("\r\n first message[%d] = %p,",i,message[i]);
ret = rtl_crypto_aes_ecb_init(key,keylen);
if ( ret != 0 ) {
DiagPrintf("AES ECB init failed\r\n");
return ret;
}
ret = rtl_crypto_aes_ecb_encrypt(message, msglen, pIv, ivlen, pResult);
if ( ret != 0 ) {
DiagPrintf("AES ECB encrypt failed\r\n");
return ret;
}
if ( rtl_memcmpb(aes_test_ecb_res_128, pResult, msglen) == 0 )
{
DiagPrintf("AES ECB encrypt result success\r\n");
}
else {
DiagPrintf("AES ECB encrypt result failed\r\n");
}
message = pResult;
//for(int i=0;i<msglen;i++)
//printf("\r\n second message[%d] = %p,",i,message[i]);
ret = rtl_crypto_aes_ecb_decrypt(message, msglen, pIv, ivlen, pResult);
if ( ret != 0 ) {
DiagPrintf("AES ECB decrypt failed, ret=%d\r\n", ret);
return ret;
}
if ( rtl_memcmpb(aes_test_ecb_buf, pResult, msglen) == 0 )
{
DiagPrintf("AES ECB decrypt result success\r\n");
}
else {
DiagPrintf("AES ECB decrypt result failed\r\n");
}
//for(int i=0;i<msglen;i++)
//printf("\r\n last message[%d] = %p,",i,message[i]);
return 0;
}
void main(void)
{
// sample text
char rc;
//
int ret;
int loop=0;
u32 keylen= 0;
u32 ivlen = 0;
u8 *pResult;
u8 *message;
u32 *ResultLen;
u32 msglen = 0;
const u8 *key, *pIv;
key = aes_test_key;
keylen = 16;
pIv = aes_test_iv_1;
ivlen = 16;
//
message = (unsigned char *)aes_test_buf;
msglen = sizeof(aes_test_buf);
DiagPrintf("CRYPTO API Demo...\r\n");
if ( rtl_cryptoEngine_init() != 0 ) {
DiagPrintf("crypto engine init failed\r\n");
}
else
printf("init success\n");
pResult = test_result;
test_md5();
test_aes_cbc();
test_aes_ecb();
//aes_test(); //added api combined aes_cbc setkey and cryption into one function
}

View file

@ -0,0 +1,361 @@
#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"
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteReadROM(IN u32 CtrlSetting, IN u16 Addr, OUT u8 *Data, IN u8 L25OutVoltage);
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteWriteROM(IN u32 CtrlSetting, IN u16 Addr, IN u8 Data, IN u8 L25OutVoltage);
//====================================================== Start libs
//-----
int _HalEFUSEPowerSwitch8195AROM(uint8_t bWrite, uint8_t PwrState, uint8_t L25OutVoltage) {
if (PwrState == 1) {
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF) | 0x69000000); // EFUSE_UNLOCK
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & BIT_SYS_FEN_EELDR)) // REG_SYS_FUNC_EN BIT_SYS_FEN_EELDR ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_FEN_EELDR);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) & BIT_SYSON_CK_EELDR_EN)) // REG_SYS_CLK_CTRL0 BIT_SYSON_CK_EELDR_EN ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) | BIT_SYSON_CK_EELDR_EN);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & BIT_PESOC_EELDR_CK_SEL)) // REG_SYS_CLK_CTRL1 BIT_PESOC_EELDR_CK_SEL ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) | BIT_PESOC_EELDR_CK_SEL);
if (bWrite == 1)
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & 0xFFFFF0FF) | BIT_SYS_REGU_LDO25E_EN | BIT_SYS_REGU_LDO25E_ADJ(L25OutVoltage));
}
else
{
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF); // EFUSE_UNLOCK
if ( bWrite == 1 )
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25E_EN)));
}
return bWrite;
}
//-----
int _HALEFUSEOneByteReadROM(uint32_t CtrlSetting, uint16_t Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int i = 0, ret = 0;
if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) {
_HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage);
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) & (~BIT_SYS_EF_FORCE_PGMEN));
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL,
(CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA))))
| BIT_SYS_EF_ADDR(Addr));
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
}
else while(1) {
HalDelayUs(1000);
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
break;
}
if (i++ >= 100) {
*Data = -1;
ret = 1;
break;
};
};
_HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage);
}
else *Data = -1;
return ret;
}
//-----
int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 128) > 0x1F )
result = 1;
else
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
return result;
}
//-----
int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 160) > 0x33 )
{
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
}
else
{
*Data = -1;
result = 1;
}
return result;
}
//-----
void _ReadEOTPContant(uint8_t *pContant)
{
int i;
for(i = 0; i < 32; i++ )
_HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE);
}
//-----
void _ReadEfuseContant(int UserCode, uint8_t *pContant)
{
#define EFUSE_SECTION 11
uint8_t *pbuf;
int eFuse_Addr;
int offset;
int bcnt;
int i, j;
uint8_t DataTemp0;
uint8_t DataTemp1;
pbuf = pContant;
eFuse_Addr = 0;
do {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE);
if ( DataTemp0 == 0x0FF ) break;
if ( (DataTemp0 & 0x0F) == 0x0F ) {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE);
offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1;
bcnt = (~DataTemp1) & 0x0F;
if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) {
while (bcnt)
{
if (bcnt & 1) eFuse_Addr += 2;
bcnt >>= 1;
}
}
else
{
int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3;
j = 0;
while ( bcnt )
{
if ( bcnt & 1 )
{
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE);
}
bcnt >>= 1;
j += 2;
}
}
}
else
{
for (i = (~DataTemp0) & 0x0F; i; i >>= 1 )
{
if (i & 1) eFuse_Addr += 2;
}
}
eFuse_Addr++;
}
while (eFuse_Addr <= 0x7E);
}
//-----
void _ReadEfuseContant1(uint8_t *pContant)
{
_ReadEfuseContant(0, pContant);
}
//-----
void _ReadEfuseContant2(uint8_t *pContant)
{
_ReadEfuseContant(1, pContant);
}
//-----
void _ReadEfuseContant3(uint8_t *pContant)
{
_ReadEfuseContant(2, pContant);
}
int _efuse_otp_read(u8 address, u8 len, u8 *buf)
{
u8 content[32]; // the OTP max length is 32
if((address + len) > 32) return -1;
_ReadEOTPContant(content);
_memcpy(buf, content + address, len);
return 0;
}
//====================================================== end libs
//======================================================
// OTP : one time programming
//======================================================
uint8_t buf[128];
#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes
static void efuse_otp_task(void *param)
{
int ret;
u8 i;
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]);
}
int x = 0;
while(x < 1024) {
DBG_8195A("efuse OTP block at %d:\n", x);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i++ )
// _HALEFUSEOneByteReadROM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+x, &buf[i], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadROM(0x26AF, i+x, &buf[i], L25EOUTVOLTAGE);
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i+=8){
DBG_8195A("[%04x]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i+x, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
}
x+=sizeof(buf);
}
/*
// 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);
}
//======================================================
// MTP : M? time programming
//======================================================
#define MTP_MAX_LEN 32 // The MTP max length is 32 bytes
static void efuse_mtp_task(void *param)
{
int ret;
u8 i;
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]);
}
DBG_8195A("\nefuse MTP block: Test Start\n");
// read MTP content
_memset(buf, 0xFF, MTP_MAX_LEN);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
_ReadEfuseContant1(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)
{
ConfigDebugErr = -1; // ~_DBG_GDMA_;
ConfigDebugInfo = -1; // ~_DBG_GDMA_;
ConfigDebugWarn = -1; // ~_DBG_GDMA_;
DBG_8195A("EFUSE_CTRL=%08x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL));
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__);
if(xTaskCreate(efuse_otp_task, ((const char*)"efuse_otp_task"), 512, NULL, tskIDLE_PRIORITY + 2, 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);
}

View file

@ -0,0 +1,8 @@
Example Description
This example describes how to read/write efuse in MTP.
MTP block has 32 bytes.
Requirement Components:
None

View 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);
}

View file

@ -0,0 +1,361 @@
#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"
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteReadROM(IN u32 CtrlSetting, IN u16 Addr, OUT u8 *Data, IN u8 L25OutVoltage);
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteWriteROM(IN u32 CtrlSetting, IN u16 Addr, IN u8 Data, IN u8 L25OutVoltage);
//====================================================== Start libs
//-----
int _HalEFUSEPowerSwitch8195AROM(uint8_t bWrite, uint8_t PwrState, uint8_t L25OutVoltage) {
if (PwrState == 1) {
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF) | 0x69000000); // EFUSE_UNLOCK
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & BIT_SYS_FEN_EELDR)) // REG_SYS_FUNC_EN BIT_SYS_FEN_EELDR ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_FEN_EELDR);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) & BIT_SYSON_CK_EELDR_EN)) // REG_SYS_CLK_CTRL0 BIT_SYSON_CK_EELDR_EN ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) | BIT_SYSON_CK_EELDR_EN);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & BIT_PESOC_EELDR_CK_SEL)) // REG_SYS_CLK_CTRL1 BIT_PESOC_EELDR_CK_SEL ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) | BIT_PESOC_EELDR_CK_SEL);
if (bWrite == 1)
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & 0xFFFFF0FF) | BIT_SYS_REGU_LDO25E_EN | BIT_SYS_REGU_LDO25E_ADJ(L25OutVoltage));
}
else
{
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF); // EFUSE_UNLOCK
if ( bWrite == 1 )
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25E_EN)));
}
return bWrite;
}
//-----
int _HALEFUSEOneByteReadROM(uint32_t CtrlSetting, uint16_t Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int i = 0, ret = 0;
if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) {
_HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage);
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) & (~BIT_SYS_EF_FORCE_PGMEN));
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL,
(CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA))))
| BIT_SYS_EF_ADDR(Addr));
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
}
else while(1) {
HalDelayUs(1000);
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
break;
}
if (i++ >= 100) {
*Data = -1;
ret = 1;
break;
};
};
_HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage);
}
else *Data = -1;
return ret;
}
//-----
int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 128) > 0x1F )
result = 1;
else
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
return result;
}
//-----
int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 160) > 0x33 )
{
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
}
else
{
*Data = -1;
result = 1;
}
return result;
}
//-----
void _ReadEOTPContant(uint8_t *pContant)
{
int i;
for(i = 0; i < 32; i++ )
_HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE);
}
//-----
void _ReadEfuseContant(int UserCode, uint8_t *pContant)
{
#define EFUSE_SECTION 11
uint8_t *pbuf;
int eFuse_Addr;
int offset;
int bcnt;
int i, j;
uint8_t DataTemp0;
uint8_t DataTemp1;
pbuf = pContant;
eFuse_Addr = 0;
do {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE);
if ( DataTemp0 == 0x0FF ) break;
if ( (DataTemp0 & 0x0F) == 0x0F ) {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE);
offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1;
bcnt = (~DataTemp1) & 0x0F;
if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) {
while (bcnt)
{
if (bcnt & 1) eFuse_Addr += 2;
bcnt >>= 1;
}
}
else
{
int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3;
j = 0;
while ( bcnt )
{
if ( bcnt & 1 )
{
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE);
}
bcnt >>= 1;
j += 2;
}
}
}
else
{
for (i = (~DataTemp0) & 0x0F; i; i >>= 1 )
{
if (i & 1) eFuse_Addr += 2;
}
}
eFuse_Addr++;
}
while (eFuse_Addr <= 0x7E);
}
//-----
void _ReadEfuseContant1(uint8_t *pContant)
{
_ReadEfuseContant(0, pContant);
}
//-----
void _ReadEfuseContant2(uint8_t *pContant)
{
_ReadEfuseContant(1, pContant);
}
//-----
void _ReadEfuseContant3(uint8_t *pContant)
{
_ReadEfuseContant(2, pContant);
}
int _efuse_otp_read(u8 address, u8 len, u8 *buf)
{
u8 content[32]; // the OTP max length is 32
if((address + len) > 32) return -1;
_ReadEOTPContant(content);
_memcpy(buf, content + address, len);
return 0;
}
//====================================================== end libs
//======================================================
// OTP : one time programming
//======================================================
uint8_t buf[128];
#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes
static void efuse_otp_task(void *param)
{
int ret;
u8 i;
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]);
}
int x = 0;
while(x < 1024) {
DBG_8195A("efuse OTP block at %d:\n", x);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i++ )
// _HALEFUSEOneByteReadROM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+x, &buf[i], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadROM(0x26AF, i+x, &buf[i], L25EOUTVOLTAGE);
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i+=8){
DBG_8195A("[%04x]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i+x, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
}
x+=sizeof(buf);
}
/*
// 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);
}
//======================================================
// MTP : M? time programming
//======================================================
#define MTP_MAX_LEN 32 // The MTP max length is 32 bytes
static void efuse_mtp_task(void *param)
{
int ret;
u8 i;
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]);
}
DBG_8195A("\nefuse MTP block: Test Start\n");
// read MTP content
_memset(buf, 0xFF, MTP_MAX_LEN);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
_ReadEfuseContant1(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)
{
ConfigDebugErr = -1; // ~_DBG_GDMA_;
ConfigDebugInfo = -1; // ~_DBG_GDMA_;
ConfigDebugWarn = -1; // ~_DBG_GDMA_;
DBG_8195A("EFUSE_CTRL=%08x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL));
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__);
if(xTaskCreate(efuse_otp_task, ((const char*)"efuse_otp_task"), 512, NULL, tskIDLE_PRIORITY + 2, 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);
}

View 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

View 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);
}

View file

@ -0,0 +1,361 @@
#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"
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteReadROM(IN u32 CtrlSetting, IN u16 Addr, OUT u8 *Data, IN u8 L25OutVoltage);
_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteWriteROM(IN u32 CtrlSetting, IN u16 Addr, IN u8 Data, IN u8 L25OutVoltage);
//====================================================== Start libs
//-----
int _HalEFUSEPowerSwitch8195AROM(uint8_t bWrite, uint8_t PwrState, uint8_t L25OutVoltage) {
if (PwrState == 1) {
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF) | 0x69000000); // EFUSE_UNLOCK
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & BIT_SYS_FEN_EELDR)) // REG_SYS_FUNC_EN BIT_SYS_FEN_EELDR ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_FEN_EELDR);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) & BIT_SYSON_CK_EELDR_EN)) // REG_SYS_CLK_CTRL0 BIT_SYSON_CK_EELDR_EN ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) | BIT_SYSON_CK_EELDR_EN);
if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & BIT_PESOC_EELDR_CK_SEL)) // REG_SYS_CLK_CTRL1 BIT_PESOC_EELDR_CK_SEL ?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) | BIT_PESOC_EELDR_CK_SEL);
if (bWrite == 1)
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & 0xFFFFF0FF) | BIT_SYS_REGU_LDO25E_EN | BIT_SYS_REGU_LDO25E_ADJ(L25OutVoltage));
}
else
{
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF); // EFUSE_UNLOCK
if ( bWrite == 1 )
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25E_EN)));
}
return bWrite;
}
//-----
int _HALEFUSEOneByteReadROM(uint32_t CtrlSetting, uint16_t Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int i = 0, ret = 0;
if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) {
_HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage);
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) & (~BIT_SYS_EF_FORCE_PGMEN));
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL,
(CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA))))
| BIT_SYS_EF_ADDR(Addr));
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
}
else while(1) {
HalDelayUs(1000);
if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) {
*Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL);
ret = 1;
break;
}
if (i++ >= 100) {
*Data = -1;
ret = 1;
break;
};
};
_HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage);
}
else *Data = -1;
return ret;
}
//-----
int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 128) > 0x1F )
result = 1;
else
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
return result;
}
//-----
int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage)
{
int result;
if ( (unsigned int)(Addr - 160) > 0x33 )
{
result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage);
}
else
{
*Data = -1;
result = 1;
}
return result;
}
//-----
void _ReadEOTPContant(uint8_t *pContant)
{
int i;
for(i = 0; i < 32; i++ )
_HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE);
}
//-----
void _ReadEfuseContant(int UserCode, uint8_t *pContant)
{
#define EFUSE_SECTION 11
uint8_t *pbuf;
int eFuse_Addr;
int offset;
int bcnt;
int i, j;
uint8_t DataTemp0;
uint8_t DataTemp1;
pbuf = pContant;
eFuse_Addr = 0;
do {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE);
if ( DataTemp0 == 0x0FF ) break;
if ( (DataTemp0 & 0x0F) == 0x0F ) {
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE);
offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1;
bcnt = (~DataTemp1) & 0x0F;
if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) {
while (bcnt)
{
if (bcnt & 1) eFuse_Addr += 2;
bcnt >>= 1;
}
}
else
{
int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3;
j = 0;
while ( bcnt )
{
if ( bcnt & 1 )
{
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE);
}
bcnt >>= 1;
j += 2;
}
}
}
else
{
for (i = (~DataTemp0) & 0x0F; i; i >>= 1 )
{
if (i & 1) eFuse_Addr += 2;
}
}
eFuse_Addr++;
}
while (eFuse_Addr <= 0x7E);
}
//-----
void _ReadEfuseContant1(uint8_t *pContant)
{
_ReadEfuseContant(0, pContant);
}
//-----
void _ReadEfuseContant2(uint8_t *pContant)
{
_ReadEfuseContant(1, pContant);
}
//-----
void _ReadEfuseContant3(uint8_t *pContant)
{
_ReadEfuseContant(2, pContant);
}
int _efuse_otp_read(u8 address, u8 len, u8 *buf)
{
u8 content[32]; // the OTP max length is 32
if((address + len) > 32) return -1;
_ReadEOTPContant(content);
_memcpy(buf, content + address, len);
return 0;
}
//====================================================== end libs
//======================================================
// OTP : one time programming
//======================================================
uint8_t buf[128];
#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes
static void efuse_otp_task(void *param)
{
int ret;
u8 i;
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]);
}
int x = 0;
while(x < 1024) {
DBG_8195A("efuse OTP block at %d:\n", x);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i++ )
// _HALEFUSEOneByteReadROM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+x, &buf[i], L25EOUTVOLTAGE);
_HALEFUSEOneByteReadROM(0x26AF, i+x, &buf[i], L25EOUTVOLTAGE);
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
for(i = 0; i < sizeof(buf); i+=8){
DBG_8195A("[%04x]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i+x, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
}
x+=sizeof(buf);
}
/*
// 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);
}
//======================================================
// MTP : M? time programming
//======================================================
#define MTP_MAX_LEN 32 // The MTP max length is 32 bytes
static void efuse_mtp_task(void *param)
{
int ret;
u8 i;
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]);
}
DBG_8195A("\nefuse MTP block: Test Start\n");
// read MTP content
_memset(buf, 0xFF, MTP_MAX_LEN);
device_mutex_lock(RT_DEV_LOCK_EFUSE);
_ReadEfuseContant1(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)
{
ConfigDebugErr = -1; // ~_DBG_GDMA_;
ConfigDebugInfo = -1; // ~_DBG_GDMA_;
ConfigDebugWarn = -1; // ~_DBG_GDMA_;
DBG_8195A("EFUSE_CTRL=%08x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL));
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__);
if(xTaskCreate(efuse_otp_task, ((const char*)"efuse_otp_task"), 512, NULL, tskIDLE_PRIORITY + 2, 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);
}

View file

@ -0,0 +1,10 @@
Example Description
This example describes how to read/write efuse in user blocks.
There are three blocks, each block has 32 bytes.
Requirement Components:
None

View file

@ -0,0 +1,137 @@
#include "diag.h"
#include "hal_efuse.h"
void main(void)
{
// There are three blocks, each block has 32 bytes.
u8 CodeWordNum; // 0~3, 0: 1~8 bytes, 1: 9~16 bytes, 2: 17~24 bytes, 3: 25~32 bytes
u8 WordEnable; // 0x0~0xF, 4bits, 1 bit is for 2 bytes, Max: 8 bytes.
// bit0: 1,2 byte , bit1: 3,4 byte , bit2: 5,6 byte , bit3: 7,8 byte
u8 content[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
u8 i;
// Block 1
u8 text1_0[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
u8 text1_1[8] = {0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
u8 text1_2[8] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17};
u8 text1_3[8] = {0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
// Block 2
u8 text2_0[8] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};
u8 text2_1[8] = {0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F};
u8 text2_2[8] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37};
u8 text2_3[8] = {0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F};
// Block 3
u8 text3_0[8] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
u8 text3_1[8] = {0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F};
u8 text3_2[8] = {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57};
u8 text3_3[8] = {0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F};
u8 bWriteBlock1 = 0;
u8 bWriteBlock2 = 0;
u8 bWriteBlock3 = 0;
DBG_8195A("\nefuse user block: Test Start\n");
//------------------------------------------------//
// efuse user block 1 //
//------------------------------------------------//
// write efuse user block 1
if(bWriteBlock1){
// write 1~8 bytes in block 1
CodeWordNum = 0;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_0) == _SUCCESS);
DBG_8195A("write 1~8 bytes of block 1 success.\n");
// write 9~16 bytes in block 1
CodeWordNum = 1;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_1) == _SUCCESS);
DBG_8195A("write 9~16 bytes of block 1 success.\n");
// write 17~24 bytes in block 1
CodeWordNum = 2;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_2) == _SUCCESS);
DBG_8195A("write 17~24 bytes of block 1 success.\n");
// write 25~32 bytes in block 1
CodeWordNum = 3;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant1(CodeWordNum, WordEnable, text1_3) == _SUCCESS);
DBG_8195A("write 25~32 bytes of block 1 success.\n");
}
// read efuse user block 1, read 32 bytes once.
_memset(content, 0, 32);
ReadEfuseContant1(content);
DBG_8195A("efuse user block 1 :\n");
for(i=0; i<32; i++){
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
}
//------------------------------------------------//
// efuse user block 2 //
//------------------------------------------------//
// write efuse user block 2
if(bWriteBlock2){
// write 1~8 bytes in block 2
CodeWordNum = 0;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_0) == _SUCCESS);
DBG_8195A("write 1~8 bytes of block 2 success.\n");
// write 9~16 bytes in block 2
CodeWordNum = 1;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_1) == _SUCCESS);
DBG_8195A("write 9~16 bytes of block 2 success.\n");
// write 17~24 bytes in block 2
CodeWordNum = 2;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_2) == _SUCCESS);
DBG_8195A("write 17~24 bytes of block 2 success.\n");
// write 25~32 bytes in block 2
CodeWordNum = 3;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant2(CodeWordNum, WordEnable, text2_3) == _SUCCESS);
DBG_8195A("write 25~32 bytes of block 2 success.\n");
}
// read efuse user block 2, read 32 bytes once.
_memset(content, 0, 32);
ReadEfuseContant2(content);
DBG_8195A("efuse user block 2 :\n");
for(i=0; i<32; i++){
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
}
//------------------------------------------------//
// efuse user block 3 //
//------------------------------------------------//
// write efuse user block 3
if(bWriteBlock3){
// write 1~8 bytes in block 3
CodeWordNum = 0;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_0) == _SUCCESS);
DBG_8195A("write 1~8 bytes of block 3 success.\n");
// write 9~16 bytes in block 3
CodeWordNum = 1;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_1) == _SUCCESS);
DBG_8195A("write 9~16 bytes of block 3 success.\n");
// write 17~24 bytes in block 3
CodeWordNum = 2;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_2) == _SUCCESS);
DBG_8195A("write 17~24 bytes of block 3 success.\n");
// write 25~32 bytes in block 3
CodeWordNum = 3;
WordEnable = 0xF; // max: 8 bytes
if(WriteEfuseContant3(CodeWordNum, WordEnable, text3_3) == _SUCCESS);
DBG_8195A("write 25~32 bytes of block 3 success.\n");
}
// read efuse user block 3, read 32 bytes once.
_memset(content, 0, 32);
ReadEfuseContant3(content);
DBG_8195A("efuse user block 3 :\n");
for(i=0; i<32; i++){
DBG_8195A("[%d]\t0x%02x\n", i+1, content[i]);
}
DBG_8195A("efuse user block: Test Done\n");
for(;;);
}

View 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
}

View file

@ -0,0 +1,102 @@
/*
* Test: Speed rd Flash
*/
#include "rtl8195a.h"
//#include "cortex.h"
//#include "rtl8710.h"
//#include "rom_lib.h"
//#include "mask.h"
#include "core_cm3.h"
#include "flash_api.h"
//extern uint8_t __StackTop;
int main(void)
{
u32 t[10];
int i = 333333, x = SpicDualBitMode + 1;
HalPinCtrlRtl8195A(JTAG, 0, 1);
HalCpuClkConfig(1); // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz
ConfigDebugErr = -1;
ConfigDebugInfo = -1;
ConfigDebugWarn = -1;
VectorTableInitRtl8195A(0x1FFFFFFC);
HalInitPlatformLogUartV02();
HalInitPlatformTimerV02();
HalShowBuildInfoV02();
flash_turnon();
flash_init(&flashobj);
// HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); // SPI_FLASH_PIN_FCTRL(ON); // enable spi flash pins
// SpicLoadInitParaFromClockRtl8195AV02();
// SpicInitRtl8195AV02(2, SpicDualBitMode); //
// SpicWaitBusyDoneRtl8195A();
DiagPrintf("Flash[0]: 0x%08X\r\n", *(volatile u32 *)SPI_FLASH_BASE );
// HalDelayUs(1000000);
DiagPrintf("CPU CLK : %d Hz\r\n", HalGetCpuClk());
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
if(!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) {
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
while(x) {
x--;
DiagPrintf("<---- Init %d ---->\n", x);
if (!SpicFlashInitRtl8195A(x)) {// SpicOneBitMode)){
DiagPrintf("SPI Init Fail!!!!!!\n"); // DBG_SPIF_ERR?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3)|0xf);
while(1);
}
t[0] = DWT->CYCCNT;
DiagPrintf("Test: t0 = %d\r\n", DWT->CYCCNT - t[0]);
t[0] = DWT->CYCCNT;
volatile u32 * ptr = (volatile u32 *)SPI_FLASH_BASE+0x4000;
for(i=0; i < 16384; i++) *ptr++;
t[1] = DWT->CYCCNT - t[0];
DiagPrintf("read(): tFlash = %d, clk/byte = %d\r\n", t[1], t[1] >> 16);
ptr = (volatile u32 *)SPI_FLASH_BASE+0x10000;
t[0] = DWT->CYCCNT;
memcpy((u8 *)0x10060000,(u8 *) SPI_FLASH_BASE+0x10000, 65536);
for(i=0; i < 16384; i++) *ptr++;
t[2] = DWT->CYCCNT - t[0];
DiagPrintf("memcpy(): tFlash = %d, clk/byte = %d\r\n", t[2], t[2] >> 16);
ptr = (volatile u32 *)0x10060000;
t[0] = DWT->CYCCNT;
for(i=0; i < 16384; i++) *ptr++;
t[3] = DWT->CYCCNT - t[0];
DiagPrintf("Speed rd RAM = %d, clk/byte = %d\r\n", t[3], t[3]>>16);
ptr = (volatile u32 *)0x1FFF0000;
t[0] = DWT->CYCCNT;
for(i=0; i < 16384; i++) *ptr++;
t[4] = DWT->CYCCNT - t[0];
DiagPrintf("Speed rd TCM = %d, clk/byte = %d\r\n", t[4], t[4]>>16);
DiagPrintf("read(): tFlash/tTCM = %d, tFlash/tRAM = %d\r\n", t[1]/t[4], t[1]/t[3]);
DiagPrintf("memcpy(): tFlash/tTCM = %d, tFlash/tRAM = %d\r\n", t[2]/t[4], t[2]/t[3]);
t[0] = DWT->CYCCNT;
SpicUserReadRtl8195A(16384*2, 0, (u8 *)0x10060000, x);
t[1] = DWT->CYCCNT - t[0];
DiagPrintf("Spic 1Read to RAM = %d, clk/byte = %d\r\n", t[1], t[1]>>16);
t[0] = DWT->CYCCNT;
SpicUserReadFourByteRtl8195A(16384*2, 0, (u32 *)0x10060000, x);
t[1] = DWT->CYCCNT - t[0];
DiagPrintf("Spic 4Read to RAM = %d, clk/byte = %d\r\n", t[1], t[1]>>16);
t[0] = DWT->CYCCNT;
SpicUserReadRtl8195A(16384*2, 0, (u8 *)0x1FFF0000, x);
t[1] = DWT->CYCCNT - t[0];
DiagPrintf("Spic 1Read to TCM = %d, clk/byte = %d\r\n", t[1], t[1]>>16);
t[0] = DWT->CYCCNT;
SpicUserReadFourByteRtl8195A(16384*2, 0, (u32 *)0x1FFF0000, x);
t[1] = DWT->CYCCNT - t[0];
DiagPrintf("Spic 4Read to TCM = %d, clk/byte = %d\r\n", t[1], t[1]>>16);
}
DiagPrintf("Flash[0]: 0x%08X\r\n", *(volatile u32 *)SPI_FLASH_BASE );
DiagPrintf("End");
while(1);
}

View file

@ -0,0 +1,8 @@
Example Description
This example read a specific flash offset, modify it and re-read again.
Requirement Components:
None

View 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);
}

View file

@ -0,0 +1,158 @@
/*
* Routines to access hardware
*
* Copyright (c) 2015 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "device.h"
#include "diag.h"
#include "main.h"
#include "dma_api.h"
#if 1
//Multi-Block Example Demo
#define DMA_CPY_LEN 176
#define DMA_BLOCK_LENGTH 22
#define DMA_SRC_OFFSET 0
#define DMA_DST_OFFSET 0
#define BLOCK_NUM 8
gdma_t gdma;
uint8_t TestBuf1[DMA_CPY_LEN];
uint8_t TestBuf2[DMA_CPY_LEN];
volatile uint8_t dma_done;
struct BlockInfo{
u32 SrcAddr;
u32 DstAddr;
u32 BlockLength;
u32 SrcOffset;
u32 DstOffset;
};
void dma_done_handler(uint32_t id) {
DiagPrintf("DMA Copy Done!!\r\n");
dma_done = 1;
}
int main(void) {
int i = 0,err = 0;
struct BlockInfo block_info[BLOCK_NUM];
//Set how many blocks we want to transfer (16 at most)
gdma.gdma_obj.BlockNum = BLOCK_NUM;
//Initialize DMA multi-block mode setting
dma_memcpy_aggr_init(&gdma, dma_done_handler, (uint32_t) &gdma);
_memset(TestBuf1, 0,DMA_CPY_LEN);
for(i = 0; i < DMA_CPY_LEN; i++){
TestBuf1[i] = DMA_CPY_LEN - 1 - i;
}
_memset(TestBuf2, 0,DMA_CPY_LEN);
dma_done = 0;
for(i = 0; i < BLOCK_NUM; i++){
//User can decide the relation between SrcOffset/DstOffset,SrcAddr/DstAddr and Block length
// For example :
//block_info[i].SrcOffset = 0;
//block_info[i].DstOffset = 4;
//block_info[i].SrcAddr = &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC
//block_info[i].DstAddr = &TestBuf2[0] + (DMA_BLOCK_LENGTH + block_info[i].DstOffset )*i;//Dest
//block_info[i].BlockLength = DMA_BLOCK_LENGTH;
block_info[i].SrcOffset = 0;
block_info[i].DstOffset = 0;
block_info[i].SrcAddr = (uint32_t) &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC
block_info[i].DstAddr = (uint32_t) &TestBuf2[ i * DMA_BLOCK_LENGTH] ;//Dest
block_info[i].BlockLength = DMA_BLOCK_LENGTH;
//DiagPrintf("block_info[%d].SrcAddr = %x\r\n",i, block_info[i].SrcAddr);
//DiagPrintf("block_info[%d].DstAddr = %x\r\n",i, block_info[i].DstAddr);
//DiagPrintf("block_info[%d].BlockLength = %x\r\n",i, block_info[i].BlockLength);
//DiagPrintf("block_info[%d].SrcOffset = %x\r\n",i, block_info[i].SrcOffset);
//DiagPrintf("block_info[%d].DstOffset = %x\r\n",i, block_info[i].DstOffset);
}
dma_memcpy_aggr(&gdma, (PHAL_GDMA_BLOCK) &block_info);
while (dma_done == 0);
err = 0;
for (i=0;i<DMA_CPY_LEN;i++) {
//DiagPrintf("dma_done = %x\r\n", dma_done);
//DiagPrintf("TestBuf2[%d] = %x\r\n",i, TestBuf2[i]);
if (TestBuf2[i+DMA_DST_OFFSET] != TestBuf1[i+DMA_SRC_OFFSET]) {
DiagPrintf("DMA Copy Memory Compare Err, %d %x %x\r\n", i, TestBuf1[i+DMA_SRC_OFFSET], TestBuf2[i+DMA_DST_OFFSET]);
DiagPrintf("DMA done = %x\r\n", dma_done);
err = 1;
break;
}
}
if (!err) {
DiagPrintf("DMA Copy Memory Compare OK!! %x\r\n", TestBuf2[DMA_DST_OFFSET+DMA_CPY_LEN - 1]);
}
HalGdmaMemCpyDeInit(&(gdma.gdma_obj));
while(1);
return 0;
}
#else
//Single-Block Example Demo
#define DMA_CPY_LEN 256
#define DMA_SRC_OFFSET 0
#define DMA_DST_OFFSET 0
gdma_t gdma;
uint8_t TestBuf1[512];
uint8_t TestBuf2[512];
volatile uint8_t dma_done;
void dma_done_handler(uint32_t id) {
DiagPrintf("DMA Copy Done!!\r\n");
dma_done = 1;
}
int main(void) {
int i;
int err;
dma_memcpy_init(&gdma, dma_done_handler, (uint32_t)&gdma);
for (i=0;i< 512;i++) {
TestBuf1[i] = i;
}
_memset(TestBuf2, 0xff, 512);
dma_done = 0;
dma_memcpy(&gdma, TestBuf2+DMA_DST_OFFSET, TestBuf1+DMA_SRC_OFFSET, DMA_CPY_LEN);
while (dma_done == 0);
err = 0;
for (i=0;i<DMA_CPY_LEN;i++) {
if (TestBuf2[i+DMA_DST_OFFSET] != TestBuf1[i+DMA_SRC_OFFSET]) {
DiagPrintf("DMA Copy Memory Compare Err, %d %x %x\r\n", i, TestBuf1[i+DMA_SRC_OFFSET], TestBuf2[i+DMA_DST_OFFSET]);
err = 1;
break;
}
}
if (!err) {
DiagPrintf("DMA Copy Memory Compare OK!! %x\r\n", TestBuf2[DMA_DST_OFFSET+DMA_CPY_LEN]);
}
HalGdmaMemCpyDeInit(&(gdma.gdma_obj));
while(1);
return 0;
}
#endif

View 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.

View 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);
}
}
}

View 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.

View 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);
}

View 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.

View 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 (;;);
}

View 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.

View 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)(&current_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");
}
}

View file

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

View file

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

View 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

View 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

View file

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

View file

@ -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);
}
}

View 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

View 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);
}
}
}

View 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.

View 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();
}

View 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

View 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);
}
}

View 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.

View 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_SINGLE_BOARD
#undef I2C_SINGLE_BOARD
#ifndef I2C_SINGLE_BOARD
#define I2C_DUAL_BOARD
#endif
#ifdef I2C_SINGLE_BOARD
#define I2C_MASTER_DEVICE
#define I2C_SLAVE_DEVICE
#endif
#ifdef I2C_DUAL_BOARD
//#define I2C_MASTER_DEVICE
#ifndef I2C_MASTER_DEVICE
#define I2C_SLAVE_DEVICE
#endif
#endif
#define I2C_RESTART_DEMO // test restart
#ifdef I2C_DUAL_BOARD
// 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){;}
// 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){;}
#else // #ifdef I2C_DUAL_BOARD
// Slave
// Rx
#define CLEAR_SLV_RXC_FLAG
#define SET_SLV_RXC_FLAG
#define WAIT_SLV_RXC
// Tx
#define CLEAR_SLV_TXC_FLAG
#define SET_SLV_TXC_FLAG
#define WAIT_SLV_TXC
// Master
// Rx
#define CLEAR_MST_RXC_FLAG
#define SET_MST_RXC_FLAG
#define WAIT_MST_RXC
// Tx
#define CLEAR_MST_TXC_FLAG
#define SET_MST_TXC_FLAG
#define WAIT_MST_TXC
#endif // #ifdef I2C_DUAL_BOARD
#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;
void i2c_slave_rxc_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 < 1; i2clocalcnt++) {
if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt]) {
result = 0;
break;
}
}
DBG_8195A("\r\nSlave receive: Result is %s\r\n", (result) ? "success" : "fail");
_memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH);
SET_SLV_RXC_FLAG;
}
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)
{
//DBG_8195A("stxc\n");
SET_SLV_TXC_FLAG;
}
void i2c_master_txc_callback(void *userdata)
{
//DBG_8195A("mtxc\n");
SET_MST_TXC_FLAG;
}
void i2c_master_err_callback(void *userdata)
{
DBG_8195A("ERRRRRR:%x\n", i2cmaster.SalI2CHndPriv.SalI2CHndPriv.ErrType);
}
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);
}
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_TXC_FLAG;
i2c_slave_write(&i2cslave, &i2cdatardsrc[0], I2C_DATA_LENGTH);
WAIT_SLV_TXC;
}
void main(void)
{
int i2clocalcnt;
// 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;
}
// ------- Single board -------
#ifdef I2C_SINGLE_BOARD
demo_i2c_master_enable();
demo_i2c_slave_enable();
// Master write - Slave read
demo_i2c_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_slave_read_1byte();
demo_i2c_master_write_1byte();
#endif
demo_i2c_slave_write();
demo_i2c_master_read();
#endif
//================================================================
// ------- Dual board -------
#ifdef I2C_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();
// 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
#endif // #ifdef I2C_DUAL_BOARD
while(1){;}
}

View file

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

View file

@ -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);
}

View file

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

View file

@ -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_ */

View file

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

View file

@ -0,0 +1,165 @@
/*******************************************************************************
* 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;
int should_stop = 0;
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
if(should_stop)
break;
}
//Step5. Stop
stop();
free(data);
}
/*******************************************************************************
* initialize ic parameters
*******************************************************************************/
/*******************************************************************************
* read rawdata
*******************************************************************************/

View file

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

View 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);
}
}

View file

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

View file

@ -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);
}
}

View 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

View file

@ -0,0 +1,183 @@
#include <stdio.h>
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include <osdep_api.h>
#include "i2c_api.h"
#include "pinmap.h"
//#define I2C_MTR_SDA PC_4//PB_3
//#define I2C_MTR_SCL PC_5//PB_2
#define I2C_MTR_SDA PB_3
#define I2C_MTR_SCL PB_2
#define I2C_BUS_CLK 100000 //hz
#define I2C_ALC5651_ADDR (0x34/2)
#define RT5651_PRIV_INDEX 0x6a
#define RT5651_PRIV_DATA 0x6c
#if defined (__ICCARM__)
i2c_t alc5651_i2c;
#else
volatile i2c_t alc5651_i2c;
#define printf DBG_8195A
#endif
static void alc5651_delay(void)
{
int i;
i=10000;
while (i) {
i--;
asm volatile ("nop\n\t");
}
}
void alc5651_reg_write(unsigned int reg, unsigned int value)
{
char buf[4];
buf[0] = (char)reg;
buf[1] = (char)(value>>8);
buf[2] = (char)(value&0xff);
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
alc5651_delay();
}
void alc5651_reg_read(unsigned int reg, unsigned int *value)
{
int tmp;
char *buf = (char*)&tmp;
buf[0] = (char)reg;
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
alc5651_delay();
buf[0] = 0xaa;
buf[1] = 0xaa;
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
alc5651_delay();
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
}
void alc5651_index_write(unsigned int reg, unsigned int value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_write(RT5651_PRIV_DATA, value);
}
void alc5651_index_read(unsigned int reg, unsigned int *value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_read(RT5651_PRIV_DATA, value);
}
void alc5651_reg_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec reg dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_reg_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_index_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec index dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_index_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_init(void)
{
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
}
void alc5651_set_word_len(int len_idx) // interface2
{
// 0: 16 1: 20 2: 24 3: 8
unsigned int val;
alc5651_reg_read(0x71,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x71,val);
alc5651_reg_read(0x70,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x70,val);
}
void alc5651_init_interface1(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x27,0x3820);
alc5651_reg_write(0x77,0x0000);
}
void alc5651_init_interface2(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x28,0x3030);
alc5651_reg_write(0x2F,0x0080);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,326 @@
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "main.h"
#include "i2s_api.h"
/**
* @brief Main program.
* @param None
* @retval None
*/
#include "alc5651.c"
/*
extern void alc5651_init(void);
extern void alc5651_init_interface2(void);
extern void alc5651_reg_dump(void);
extern void alc5651_index_dump(void);
extern void alc5651_set_word_len(int len_idx);
*/
i2s_t i2s_obj;
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#define SAMPLE_FILE
#define SAMPLE_FILE_RATE 44100
#define SAMPLE_FILE_CHNUM 2
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
#if defined(SAMPLE_FILE)
// no sample
// SR_96KHZ,
// SR_7p35KHZ,
// SR_29p4KHZ,
// SR_88p2KHZ
#if SAMPLE_FILE_RATE==8000
#if SAMPLE_FILE_CHNUM==2
#include "birds_8000_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_8KHZ
#endif
#elif SAMPLE_FILE_RATE==11025
#if SAMPLE_FILE_CHNUM==2
#include "birds_11025_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_11p02KHZ
#endif
#elif SAMPLE_FILE_RATE==16000
#if SAMPLE_FILE_CHNUM==2
#include "birds_16000_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_16KHZ
#endif
#elif SAMPLE_FILE_RATE==22050
#if SAMPLE_FILE_CHNUM==2
#include "birds_22050_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_22p05KHZ
#endif
#elif SAMPLE_FILE_RATE==24000
#if SAMPLE_FILE_CHNUM==2
#include "birds_24000_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_24KHZ
#endif
#elif SAMPLE_FILE_RATE==32000
#if SAMPLE_FILE_CHNUM==2
#include "birds_32000_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_32KHZ
#endif
#elif SAMPLE_FILE_RATE==44100
#if SAMPLE_FILE_CHNUM==2
#include "birds_44100_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_44p1KHZ
#endif
#elif SAMPLE_FILE_RATE==48000
#if SAMPLE_FILE_CHNUM==2
#include "birds_48000_2ch_16b.c"
#undef SAMPLE_FILE_RATE
#define SAMPLE_FILE_RATE SR_48KHZ
#endif
#endif
#if SAMPLE_FILE_CHNUM==2
#undef SAMPLE_FILE_CHNUM
#define SAMPLE_FILE_CHNUM CH_STEREO
#endif
int curr_cnt=0;
#else
short test_sine16[16]={0, 12539/4, 23170/4, 30273/4, 32767/4, 30273/4, 23170/4, 12539/4,
0, -12539/4, -23170/4, -30273/4, -32767/4, -30273/4, -23170/4, -12539/4};
int test_sine24[16]={0, 12539*256/4, 23170*256/4, 30273*256/4, 32767*256/4, 30273*256/4, 23170*256/4, 12539*256/4,
0, -12539*256/4, -23170*256/4, -30273*256/4, -32767*256/4, -30273*256/4, -23170*256/4, -12539*256/4};
extern void wait_ms(u32);
#include <math.h>
short remap_level_to_signed_16_bit(float val)
{
val*=32767;
if(val>32767) val=32767;
if(val<-32768) val=-32768;
return val;
}
void generate_freq_16bit(short *buffer, int count, float freq, float sampling_rate)
{
int pos; // sample number we're on
for (pos = 0; pos < count; pos++) {
float a = 2 * 3.14159f * freq * pos / sampling_rate;
// convert from [-1.0,1.0] to [-32767,32767]:
buffer[pos] = remap_level_to_signed_16_bit(a);
}
}
void gen_sound_sample16(short *buf, int buf_size, int channel_num)
{
int i;
for (i = 0 ; i < buf_size ; i+=channel_num){
buf[i] = test_sine16[(i/channel_num)%16];
if(channel_num>=2)
buf[i+1] = test_sine16[(i/channel_num)%16];
}
}
void gen_sound_sample24(int *buf, int buf_size, int channel_num)
{
int i;
for (i = 0 ; i < buf_size ; i+=channel_num){
buf[i] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
if(channel_num>=2)
//buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF;
}
}
#if 0
void test_delay(int sec)
{
for(int i=0;i<166*1000*100*sec;i++)
asm(" nop");
}
#endif
int test_rate_list[12] = {
SR_8KHZ,
SR_16KHZ,
SR_24KHZ,
SR_32KHZ,
SR_48KHZ,
SR_96KHZ,
SR_7p35KHZ,
SR_11p02KHZ,
SR_22p05KHZ,
SR_29p4KHZ,
SR_44p1KHZ,
SR_88p2KHZ
};
#endif
void test_tx_complete(void *data, char *pbuf)
{
int *ptx_buf;
i2s_t *obj = (i2s_t *)data;
static u32 count=0;
//DBG_8195A_I2S_LVL(VERI_I2S_LVL, "I2S%d %s\n",pI2SDemoHnd->DevNum,__func__);
count++;
if ((count&1023) == 1023)
{
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ",\n");
}
ptx_buf = i2s_get_tx_page(obj);
//ptx_buf = (int*)pbuf;
#if defined(SAMPLE_FILE)
_memcpy((void*)ptx_buf, (void*)&sample[curr_cnt], I2S_DMA_PAGE_SIZE);
curr_cnt+=(I2S_DMA_PAGE_SIZE/sizeof(short));
if(curr_cnt >= sample_size*(obj->channel_num==CH_MONO?1:2)) {
curr_cnt = 0;
}
#else
if(obj->word_length == WL_16b){
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), obj->channel_num==CH_MONO?1:2);
}else{
gen_sound_sample24((int*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(int), obj->channel_num==CH_MONO?1:2);
}
#endif
i2s_send_page(obj, (uint32_t*)ptx_buf);
}
void test_rx_complete(void *data, char* pbuf)
{
i2s_t *obj = (i2s_t *)data;
int *ptx_buf;
static u32 count=0;
count++;
if ((count&1023) == 1023)
{
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n");
}
ptx_buf = i2s_get_tx_page(obj);
_memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE);
i2s_recv_page(obj); // submit a new page for receive
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
}
void main(void)
{
int *ptx_buf;
int i,j;
alc5651_init();
alc5651_init_interface2(); // connect to ALC interface 2
// dump register
//alc5651_reg_dump();
//alc5651_index_dump();
// I2S init
i2s_obj.channel_num = CH_MONO;//CH_STEREO;
i2s_obj.sampling_rate = SR_44p1KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_TXRX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
#if defined(SAMPLE_FILE)
i2s_set_param(&i2s_obj,SAMPLE_FILE_CHNUM,SAMPLE_FILE_RATE,WL_16b);
for (i=0;i<I2S_DMA_PAGE_NUM;i++) {
ptx_buf = i2s_get_tx_page(&i2s_obj);
if (ptx_buf) {
_memcpy((void*)ptx_buf, (void*)&sample[curr_cnt], I2S_DMA_PAGE_SIZE);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
curr_cnt+=(I2S_DMA_PAGE_SIZE/sizeof(short));
if(curr_cnt >= sample_size*(i2s_obj.channel_num==CH_MONO?1:2)) {
curr_cnt = 0;
}
}
}
#else
// output freq, @ sampling rate
// 6kHz @ 96kHz
// 3kHz @ 48kHz
// 2kHz @ 32kHz
// 1.5kHz @ 24kHz
// 1kHz @ 16kHz
// 500Hz @ 8kHz
// 5512.5 Hz @ 88200Hz
// 2756.25 Hz @ 44100Hz
// 1837.5 Hz @ 29400Hz
// 1378.125 Hz @ 22050Hz
// 459.375 Hz @ 7350Hz
// Stereo, 16bit
for(i=0;i<12;i++){
i2s_set_param(&i2s_obj,CH_STEREO,test_rate_list[i],WL_16b);
// Start with fill all pages of DMA buffer
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
ptx_buf = i2s_get_tx_page(&i2s_obj);
if (ptx_buf) {
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), 2);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
}
}
wait_ms(5000); // delay 5 sec.
}
// Mono, 16bit
for(i=0;i<12;i++){
i2s_set_param(&i2s_obj,CH_MONO,test_rate_list[i],WL_16b);
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
ptx_buf = i2s_get_tx_page(&i2s_obj);
if (ptx_buf) {
gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), 1);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
}
}
wait_ms(5000); // delay 5 sec.
}
// i2s_deinit(&i2s_obj);
i2s_disable(&i2s_obj);
alc5651_set_word_len(2);
alc5651_reg_dump();
i2s_enable(&i2s_obj);
// Stereo, 24bit
for(i=0;i<12;i++){
i2s_set_param(&i2s_obj,CH_STEREO,test_rate_list[i],WL_24b);
for (j=0;j<I2S_DMA_PAGE_NUM;j++) {
ptx_buf = i2s_get_tx_page(&i2s_obj);
if (ptx_buf) {
gen_sound_sample24((int*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(int), 2);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
}
}
wait_ms(5000); // delay 5 sec.
}
// Not Support Mono, 24bit
i2s_deinit(&i2s_obj);
#endif
while(1);
}

View 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

View file

@ -0,0 +1,183 @@
#include <stdio.h>
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include <osdep_api.h>
#include "i2c_api.h"
#include "pinmap.h"
//#define I2C_MTR_SDA PC_4//PB_3
//#define I2C_MTR_SCL PC_5//PB_2
#define I2C_MTR_SDA PB_3
#define I2C_MTR_SCL PB_2
#define I2C_BUS_CLK 100000 //hz
#define I2C_ALC5651_ADDR (0x34/2)
#define RT5651_PRIV_INDEX 0x6a
#define RT5651_PRIV_DATA 0x6c
#if defined (__ICCARM__)
i2c_t alc5651_i2c;
#else
volatile i2c_t alc5651_i2c;
#define printf DBG_8195A
#endif
static void alc5651_delay(void)
{
int i;
i=10000;
while (i) {
i--;
asm volatile ("nop\n\t");
}
}
void alc5651_reg_write(unsigned int reg, unsigned int value)
{
char buf[4];
buf[0] = (char)reg;
buf[1] = (char)(value>>8);
buf[2] = (char)(value&0xff);
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
alc5651_delay();
}
void alc5651_reg_read(unsigned int reg, unsigned int *value)
{
int tmp;
char *buf = (char*)&tmp;
buf[0] = (char)reg;
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
alc5651_delay();
buf[0] = 0xaa;
buf[1] = 0xaa;
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
alc5651_delay();
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
}
void alc5651_index_write(unsigned int reg, unsigned int value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_write(RT5651_PRIV_DATA, value);
}
void alc5651_index_read(unsigned int reg, unsigned int *value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_read(RT5651_PRIV_DATA, value);
}
void alc5651_reg_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec reg dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_reg_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_index_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec index dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_index_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_init(void)
{
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
}
void alc5651_set_word_len(int len_idx) // interface2
{
// 0: 16 1: 20 2: 24 3: 8
unsigned int val;
alc5651_reg_read(0x71,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x71,val);
alc5651_reg_read(0x70,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x70,val);
}
void alc5651_init_interface1(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x27,0x3820);
alc5651_reg_write(0x77,0x0000);
}
void alc5651_init_interface2(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x28,0x3030);
alc5651_reg_write(0x2F,0x0080);
}

View file

@ -0,0 +1,80 @@
/* This is software bypass example */
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "main.h"
#include "i2s_api.h"
/**
* @brief Main program.
* @param None
* @retval None
*/
#include "alc5651.c"
i2s_t i2s_obj;
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
void test_tx_complete(void *data, char *pbuf)
{
return ;
}
void test_rx_complete(void *data, char* pbuf)
{
i2s_t *obj = (i2s_t *)data;
int *ptx_buf;
static u32 count=0;
count++;
if ((count&1023) == 1023)
{
DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n");
}
ptx_buf = i2s_get_tx_page(obj);
_memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE);
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
i2s_recv_page(obj); // submit a new page for receive
}
void main(void)
{
int *ptx_buf;
int i,j;
alc5651_init();
alc5651_init_interface2(); // connect to ALC interface 2
// dump register
//alc5651_reg_dump();
//alc5651_index_dump();
// I2S init
i2s_obj.channel_num = CH_STEREO;
i2s_obj.sampling_rate = SR_44p1KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_TXRX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
/* rx need clock, let tx out first */
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));
i2s_recv_page(&i2s_obj);
while(1);
}

View file

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

View file

@ -0,0 +1,183 @@
#include <stdio.h>
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include <osdep_api.h>
#include "i2c_api.h"
#include "pinmap.h"
//#define I2C_MTR_SDA PC_4//PB_3
//#define I2C_MTR_SCL PC_5//PB_2
#define I2C_MTR_SDA PB_3
#define I2C_MTR_SCL PB_2
#define I2C_BUS_CLK 100000 //hz
#define I2C_ALC5651_ADDR (0x34/2)
#define RT5651_PRIV_INDEX 0x6a
#define RT5651_PRIV_DATA 0x6c
#if defined (__ICCARM__)
i2c_t alc5651_i2c;
#else
volatile i2c_t alc5651_i2c;
#define printf DBG_8195A
#endif
static void alc5651_delay(void)
{
int i;
i=10000;
while (i) {
i--;
asm volatile ("nop\n\t");
}
}
void alc5651_reg_write(unsigned int reg, unsigned int value)
{
char buf[4];
buf[0] = (char)reg;
buf[1] = (char)(value>>8);
buf[2] = (char)(value&0xff);
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1);
alc5651_delay();
}
void alc5651_reg_read(unsigned int reg, unsigned int *value)
{
int tmp;
char *buf = (char*)&tmp;
buf[0] = (char)reg;
i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1);
alc5651_delay();
buf[0] = 0xaa;
buf[1] = 0xaa;
i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1);
alc5651_delay();
*value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF);
}
void alc5651_index_write(unsigned int reg, unsigned int value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_write(RT5651_PRIV_DATA, value);
}
void alc5651_index_read(unsigned int reg, unsigned int *value)
{
alc5651_reg_write(RT5651_PRIV_INDEX, reg);
alc5651_reg_read(RT5651_PRIV_DATA, value);
}
void alc5651_reg_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec reg dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_reg_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_index_dump(void)
{
int i;
unsigned int value;
printf("alc5651 codec index dump\n\r");
printf("------------------------\n\r");
for(i=0;i<=0xff;i++){
alc5651_index_read(i, &value);
printf("%02x : %04x\n\r", i, (unsigned short)value);
}
printf("------------------------\n\r");
}
void alc5651_init(void)
{
i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL);
i2c_frequency(&alc5651_i2c, I2C_BUS_CLK);
}
void alc5651_set_word_len(int len_idx) // interface2
{
// 0: 16 1: 20 2: 24 3: 8
unsigned int val;
alc5651_reg_read(0x71,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x71,val);
alc5651_reg_read(0x70,&val);
val &= (~(0x3<<2));
val |= (len_idx<<2);
alc5651_reg_write(0x70,val);
}
void alc5651_init_interface1(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x27,0x3820);
alc5651_reg_write(0x77,0x0000);
}
void alc5651_init_interface2(void)
{
alc5651_reg_write(0x00,0x0021);
alc5651_reg_write(0x63,0xE8FE);
alc5651_reg_write(0x61,0x5800);
alc5651_reg_write(0x62,0x0C00);
alc5651_reg_write(0x73,0x0000);
alc5651_reg_write(0x2A,0x4242);
alc5651_reg_write(0x45,0x2000);
alc5651_reg_write(0x02,0x4848);
alc5651_reg_write(0x8E,0x0019);
alc5651_reg_write(0x8F,0x3100);
alc5651_reg_write(0x91,0x0E00);
alc5651_index_write(0x3D,0x3E00);
alc5651_reg_write(0xFA,0x0011);
alc5651_reg_write(0x83,0x0800);
alc5651_reg_write(0x84,0xA000);
alc5651_reg_write(0xFA,0x0C11);
alc5651_reg_write(0x64,0x4010);
alc5651_reg_write(0x65,0x0C00);
alc5651_reg_write(0x61,0x5806);
alc5651_reg_write(0x62,0xCC00);
alc5651_reg_write(0x3C,0x004F);
alc5651_reg_write(0x3E,0x004F);
alc5651_reg_write(0x28,0x3030);
alc5651_reg_write(0x2F,0x0080);
}

View file

@ -0,0 +1,94 @@
/* This is RX only and TX only example */
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "main.h"
#include "i2s_api.h"
/**
* @brief Main program.
* @param None
* @retval None
*/
#include "alc5651.c"
i2s_t i2s_obj;
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#define RECV_PAGE_NUM 50
u8 recv_buf[I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM];
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
u32 count = 0;
void test_tx_complete(void *data, char *pbuf)
{
i2s_t *obj = (i2s_t *)data;
int *ptx_buf;
if(count < RECV_PAGE_NUM){
ptx_buf = i2s_get_tx_page(obj);
_memcpy((void*)ptx_buf, (void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], I2S_DMA_PAGE_SIZE);
i2s_send_page(obj, (uint32_t*)ptx_buf);
count++;
}else{
count = 0;
i2s_set_direction(obj, I2S_DIR_RX);
i2s_recv_page(obj);
}
}
void test_rx_complete(void *data, char* pbuf)
{
i2s_t *obj = (i2s_t *)data;
int *ptx_buf;
if(count < RECV_PAGE_NUM){
_memcpy((void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], (void*)pbuf, I2S_DMA_PAGE_SIZE);
count++;
i2s_recv_page(obj);
}else{
count = 1;
i2s_set_direction(obj, I2S_DIR_TX);
ptx_buf = i2s_get_tx_page(obj);
_memcpy((void*)ptx_buf, (void*)recv_buf, I2S_DMA_PAGE_SIZE);
i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback
}
}
void main(void)
{
int *ptx_buf;
int i,j;
alc5651_init();
alc5651_init_interface2(); // connect to ALC interface 2
// dump register
//alc5651_reg_dump();
//alc5651_index_dump();
// I2S init
i2s_obj.channel_num = CH_MONO;
i2s_obj.sampling_rate = SR_16KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_RX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
i2s_recv_page(&i2s_obj);
while(1);
}

View file

@ -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, 38400, 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);
}
}

View 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 "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);
}
}

View file

@ -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);
}
}
}

View 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.

View 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);
}

View 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.

View 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);
}

View 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.

View 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;
}
}

View 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.

View 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);
}
}
}

View 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.

View file

@ -0,0 +1,168 @@
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "main.h"
#include <example_entry.h>
#include "freertos_pmu.h"
#include "gpio_irq_api.h"
#include "serial_api.h"
// select uart tx/rx pin with gpio interrupt function
#define UART_TX PA_4
#define UART_RX PA_0
#define LOGUART_RX_WAKE PC_1
#define WAKELOCK_EXAMPLE WAKELOCK_USER_BASE
serial_t mysobj;
volatile char rc = 0;
extern void wlan_netowrk(void);
extern void console_init(void);
char cmdbuf[128];
int cmdbuf_index = 0;
void uart_irq_callback(uint32_t id, SerialIrq event)
{
serial_t *sobj = (void*)id;
if(event == RxIrq) {
acquire_wakelock(WAKELOCK_EXAMPLE);
rc = serial_getc(sobj);
if (rc == '\r' || rc == '\n') {
serial_putc(sobj, '\r');
serial_putc(sobj, '\n');
serial_putc(sobj, '#');
serial_putc(sobj, ' ');
if (cmdbuf_index != 0) {
/* NOTICE: If you don't want loss any data from treating UART signal as GPIO interrupt,
* you can set FREERTOS_PMU_TICKLESS_PLL_RESERVED to 1 in "platform_opt.h".
* It will reserved PLL clock in tickless and UART can receive the whole data.
* But it also cost more power consumption.
**/
// process command
printf("cmd(%d): %s\r\n", cmdbuf_index, cmdbuf);
// release wakelock and reset buf
cmdbuf_index = 0;
release_wakelock(WAKELOCK_EXAMPLE);
}
}
if (!(rc == '\r' || rc == '\n' )) {
// receive command
serial_putc(sobj, rc);
cmdbuf[cmdbuf_index] = rc;
cmdbuf_index++;
cmdbuf[cmdbuf_index] = '\0';
}
}
}
void gpio_uart_rx_irq_callback(uint32_t id, gpio_irq_event event)
{
acquire_wakelock(WAKELOCK_EXAMPLE);
}
void pre_sleep_process_callback(unsigned int expected_idle_time)
{
// For peripherals that need turned off before sleep, call disable or deinit peripheral here
}
void post_sleep_process_callback(unsigned int expected_idle_time)
{
// For peripherals that are turned off before sleep, call enable or init peripheral here
}
void config_uart()
{
// setup uart
serial_init(&mysobj, UART_TX, UART_RX);
serial_baud(&mysobj, 38400);
serial_format(&mysobj, 8, ParityNone, 1);
serial_irq_handler(&mysobj, uart_irq_callback, (uint32_t)&mysobj);
serial_irq_set(&mysobj, RxIrq, 1);
serial_irq_set(&mysobj, TxIrq, 1);
// config uart rx as gpio wakeup pin
gpio_irq_t gpio_rx_wake;
gpio_irq_init(&gpio_rx_wake, UART_RX, gpio_uart_rx_irq_callback, NULL);
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
gpio_irq_enable(&gpio_rx_wake);
}
void gpio_loguart_rx_irq_callback (uint32_t id, gpio_irq_event event)
{
/* WAKELOCK_LOGUART is also handled in log service.
* It is release after a complete command is sent.
**/
acquire_wakelock(WAKELOCK_LOGUART);
}
void config_loguart()
{
/* Log uart RX pin doesn't support gpio interrupt.
* To make log uart wake system, we can parallel log uart RX with another gpio interrupt pin.
*/
gpio_irq_t gpio_rx_wake;
gpio_irq_init(&gpio_rx_wake, LOGUART_RX_WAKE, gpio_loguart_rx_irq_callback, NULL);
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
gpio_irq_enable(&gpio_rx_wake);
}
/**
* @brief Main program.
* @param None
* @retval None
*/
void main(void)
{
if ( rtl_cryptoEngine_init() != 0 ) {
DiagPrintf("crypto engine init failed\r\n");
}
/* Initialize log uart and at command service */
console_init();
/* pre-processor of application example */
pre_example_entry();
/* wlan intialization */
#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK)
wlan_network();
#endif
// setup uart with capability of wakeup system
config_uart();
// setup log uart with capability of wakeup system
config_loguart();
// By default tickless is disabled because WAKELOCK_OS is locked.
// Release this wakelock to enable tickless
release_wakelock(WAKELOCK_OS);
// Register pre/post sleep callback. They are called when system automatically enter/leave sleep.
register_sleep_callback_by_module(1, pre_sleep_process_callback, WAKELOCK_EXAMPLE);
register_sleep_callback_by_module(0, post_sleep_process_callback, WAKELOCK_EXAMPLE);
/* 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
}

View 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.

View 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();
}
}

View 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

View 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();
}
}

View file

@ -0,0 +1,7 @@
Example Description
This example describes how to use the RTC API. The RTC function is implemented by a G-Timer.
Behavior:
This example will print out the time information every secand.

View file

@ -0,0 +1,34 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#include "rtc_api.h"
int main()
{
time_t seconds;
struct tm *timeinfo;
rtc_init();
rtc_write(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37
while(1) {
seconds = rtc_read();
timeinfo = localtime(&seconds);
DBG_8195A("Time as seconds since January 1, 1970 = %d\n", seconds);
DBG_8195A("Time as a basic string = %s", ctime(&seconds));
DBG_8195A("Time as a custom formatted string = %d-%d-%d %d:%d:%d ",
timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour,
timeinfo->tm_min,timeinfo->tm_sec);
wait(1);
}
}

View 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

View 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
}

View 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.

View 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
}

View 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.

View 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);
}
//--------------------------------------------------------------------------------------------//

View file

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

View file

@ -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(;;);
}

View 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.

View 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(;;);
}

View 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$".

View 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);
}
}

View file

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

View file

@ -0,0 +1,123 @@
/*
* 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.
*/
// This example demo the function of Auto Flow control
// Please connect 2 board to run this example.
// Board1 <-----> Board2
// PA6 <-----> PA7
// PA7 <-----> PA6
// PA5 <-----> PA3
// PA3 <-----> PA5
// GND <-----> GND
// The first started 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.
#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++;
}
}
#define UART_BUF_SIZE 1000
serial_t sobj;
unsigned char buffer[UART_BUF_SIZE];
void main(void)
{
// sample text
char rc;
int i,j;
int rx_side=0;
// mbed uart test
HAL_GPIO_PullCtrl(UART_RX, PullUp);
serial_init(&sobj,UART_TX,UART_RX);
serial_baud(&sobj,38400);
serial_format(&sobj, 8, ParityNone, 1);
serial_set_flow_control(&sobj, FlowControlNone, 0, 0); // Pin assignment is ignored
for (i=0;i<1000;i++) {
// Tide Break
DBG_8195A("Wait peer ready...\r\n");
serial_putc(&sobj, i+1);
if (serial_readable(&sobj)) {
rc = serial_getc(&sobj);
if (rc > i) {
rx_side = 1;
} else {
rx_side = 0;
}
break;
}
wait_ms(100);
}
serial_clear_rx(&sobj);
// Enable flow control
serial_set_flow_control(&sobj, FlowControlRTSCTS, 0, 0); // Pin assignment is ignored
if (rx_side) {
DBG_8195A("UART Flow Control: RX ==>\r\n");
_memset(buffer, 0, UART_BUF_SIZE);
i = 0;
j = 0;
while (1) {
if (serial_readable(&sobj)) {
buffer[i] = serial_getc(&sobj);
i++;
if (i == UART_BUF_SIZE) {
break;
}
if ((i&0xf) == 0) {
// Make some delay to cause the RX FIFO full and then trigger flow controll
wait_ms(100);
DBG_8195A("UART RX got %d bytes\r\n", i);
}
j=0;
} else {
wait_ms(10);
j++;
if (j== 1000) {
DBG_8195A("UART RX Failed, Got %d bytes\r\n", i);
break;
}
}
}
} else {
DBG_8195A("UART Flow Control: TX ==>\r\n");
wait_ms(500);
for (i=0;i<UART_BUF_SIZE;i++) {
buffer[i] = 0x30 + (i%10);
}
for (i=0;i<UART_BUF_SIZE;i++) {
serial_putc(&sobj, buffer[i]);
}
}
DBG_8195A("UART Flow Control Test Done!\r\n");
while (1);
}

Some files were not shown because too many files have changed in this diff Show more