This commit is contained in:
pvvx 2017-06-21 03:00:20 +03:00
parent 34d3652711
commit 39f77eb92b
1844 changed files with 899433 additions and 7 deletions

View file

@ -0,0 +1,66 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ERROR_H
#define MBED_ERROR_H
/** To generate a fatal compile-time error, you can use the pre-processor #error directive.
*
* @code
* #error "That shouldn't have happened!"
* @endcode
*
* If the compiler evaluates this line, it will report the error and stop the compile.
*
* For example, you could use this to check some user-defined compile-time variables:
*
* @code
* #define NUM_PORTS 7
* #if (NUM_PORTS > 4)
* #error "NUM_PORTS must be less than 4"
* #endif
* @endcode
*
* Reporting Run-Time Errors:
* To generate a fatal run-time error, you can use the mbed error() function.
*
* @code
* error("That shouldn't have happened!");
* @endcode
*
* If the mbed running the program executes this function, it will print the
* message via the USB serial port, and then die with the blue lights of death!
*
* The message can use printf-style formatting, so you can report variables in the
* message too. For example, you could use this to check a run-time condition:
*
* @code
* if(x >= 5) {
* error("expected x to be less than 5, but got %d", x);
* }
* #endcode
*/
#ifdef __cplusplus
extern "C" {
#endif
void error(const char* format, ...);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,50 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ASSERT_H
#define MBED_ASSERT_H
#ifdef __cplusplus
extern "C" {
#endif
/** Internal mbed assert function which is invoked when MBED_ASSERT macro failes.
* This function is active only if NDEBUG is not defined prior to including this
* assert header file.
* In case of MBED_ASSERT failing condition, the assertation message is printed
* to stderr and mbed_die() is called.
* @param expr Expresion to be checked.
* @param file File where assertation failed.
* @param line Failing assertation line number.
*/
void mbed_assert_internal(const char *expr, const char *file, int line);
#ifdef __cplusplus
}
#endif
#ifdef NDEBUG
#define MBED_ASSERT(expr) ((void)0)
#else
#define MBED_ASSERT(expr) \
do { \
if (!(expr)) { \
mbed_assert_internal(#expr, __FILE__, __LINE__); \
} \
} while (0)
#endif
#endif

View file

@ -0,0 +1,74 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Implementation of the C time.h functions
*
* Provides mechanisms to set and read the current time, based
* on the microcontroller Real-Time Clock (RTC), plus some
* standard C manipulation and formating functions.
*
* Example:
* @code
* #include "mbed.h"
*
* int main() {
* set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37
*
* while(1) {
* time_t seconds = time(NULL);
*
* printf("Time as seconds since January 1, 1970 = %d\n", seconds);
*
* printf("Time as a basic string = %s", ctime(&seconds));
*
* char buffer[32];
* strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
* printf("Time as a custom formatted string = %s", buffer);
*
* wait(1);
* }
* }
* @endcode
*/
/** Set the current time
*
* Initialises and sets the time of the microcontroller Real-Time Clock (RTC)
* to the time represented by the number of seconds since January 1, 1970
* (the UNIX timestamp).
*
* @param t Number of seconds since January 1, 1970 (the UNIX timestamp)
*
* Example:
* @code
* #include "mbed.h"
*
* int main() {
* set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
* }
* @endcode
*/
void set_time(time_t t);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,66 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_WAIT_API_H
#define MBED_WAIT_API_H
#ifdef __cplusplus
extern "C" {
#endif
/** Generic wait functions.
*
* These provide simple NOP type wait capabilities.
*
* Example:
* @code
* #include "mbed.h"
*
* DigitalOut heartbeat(LED1);
*
* int main() {
* while (1) {
* heartbeat = 1;
* wait(0.5);
* heartbeat = 0;
* wait(0.5);
* }
* }
*/
/** Waits for a number of seconds, with microsecond resolution (within
* the accuracy of single precision floating point).
*
* @param s number of seconds to wait
*/
void wait(float s);
/** Waits a number of milliseconds.
*
* @param ms the whole number of milliseconds to wait
*/
void wait_ms(int ms);
/** Waits a number of microseconds.
*
* @param us the whole number of microseconds to wait
*/
void wait_us(int us);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,118 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include "us_ticker_api.h"
#include "cmsis.h"
static ticker_event_handler event_handler;
static ticker_event_t *head = NULL;
void us_ticker_set_handler(ticker_event_handler handler) {
us_ticker_init();
event_handler = handler;
}
void us_ticker_irq_handler(void) {
us_ticker_clear_interrupt();
/* Go through all the pending TimerEvents */
while (1) {
if (head == NULL) {
// There are no more TimerEvents left, so disable matches.
us_ticker_disable_interrupt();
return;
}
if ((int)(head->timestamp - us_ticker_read()) <= 0) {
// This event was in the past:
// point to the following one and execute its handler
ticker_event_t *p = head;
head = head->next;
if (event_handler != NULL) {
event_handler(p->id); // NOTE: the handler can set new events
}
/* Note: We continue back to examining the head because calling the
* event handler may have altered the chain of pending events. */
} else {
// This event and the following ones in the list are in the future:
// set it as next interrupt and return
us_ticker_set_interrupt(head->timestamp);
return;
}
}
}
void us_ticker_insert_event(ticker_event_t *obj, timestamp_t timestamp, uint32_t id) {
/* disable interrupts for the duration of the function */
__disable_irq();
// initialise our data
obj->timestamp = timestamp;
obj->id = id;
/* Go through the list until we either reach the end, or find
an element this should come before (which is possibly the
head). */
ticker_event_t *prev = NULL, *p = head;
while (p != NULL) {
/* check if we come before p */
if ((int)(timestamp - p->timestamp) <= 0) {
break;
}
/* go to the next element */
prev = p;
p = p->next;
}
/* if prev is NULL we're at the head */
if (prev == NULL) {
head = obj;
us_ticker_set_interrupt(timestamp);
} else {
prev->next = obj;
}
/* if we're at the end p will be NULL, which is correct */
obj->next = p;
__enable_irq();
}
void us_ticker_remove_event(ticker_event_t *obj) {
__disable_irq();
// remove this object from the list
if (head == obj) {
// first in the list, so just drop me
head = obj->next;
if (head == NULL) {
us_ticker_disable_interrupt();
} else {
us_ticker_set_interrupt(head->timestamp);
}
} else {
// find the object before me, then drop me
ticker_event_t* p = head;
while (p != NULL) {
if (p->next == obj) {
p->next = obj->next;
break;
}
p = p->next;
}
}
__enable_irq();
}

View file

@ -0,0 +1,112 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wait_api.h"
#include "us_ticker_api.h"
#include "platform_autoconf.h"
#define WAIT_US_USE_CYCCNT
#ifdef WAIT_US_USE_CYCCNT
//#include "core_cm3.h"
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
typedef struct
{
__IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
__O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
__IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
__IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
} CoreDebug_Type;
#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
__IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
__IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
__IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
__IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
__IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
__IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
__I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
__IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
__IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
__IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
uint32_t RESERVED0[1];
__IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
__IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
__IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
uint32_t RESERVED1[1];
__IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
__IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
__IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
uint32_t RESERVED2[1];
__IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
__IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
__IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
} DWT_Type;
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */
#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */
#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
#endif
void wait(float s) { // До 1073741 секунд? 298 часов
// wait_us((int)(s * 1000000.0f));
vTaskDelay((int)(s * 1000.0f));
}
void wait_ms(int ms) { // До 1073741 секунд? 298 часов
if(ms > 0) vTaskDelay(ms);
// wait_us(ms * 1000);
}
void wait_us(int us) { // До 2.147483648 секунды!
uint32_t start;
#ifdef WAIT_US_USE_CYCCNT
if(us < 1) return;
if (us < 327) { // G-timer resolution is ~31 us (1/32K), use DWT->CYCCNT...
if(!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) { // уже включен?
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // открыть доступ
DWT->CYCCNT = 0; // обнулить и запустить
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // запустить счет
}
start = DWT->CYCCNT + us * (PLATFORM_CLOCK / 1000000ul);
while ((int32_t)(start - DWT->CYCCNT) > 0);
}
else
#endif
{
start = us_ticker_read(); // G-timer resolution is ~31 us (1/32K), and is a countdown timer
while ((us_ticker_read() - start) < (uint32_t)us);
}
}

View file

@ -0,0 +1,39 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ANALOGIN_API_H
#define MBED_ANALOGIN_API_H
#include "device.h"
#if DEVICE_ANALOGIN
#ifdef __cplusplus
extern "C" {
#endif
typedef struct analogin_s analogin_t; // 444 bytes!
void analogin_init (analogin_t *obj, PinName pin);
float analogin_read (analogin_t *obj);
uint16_t analogin_read_u16(analogin_t *obj);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,42 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ANALOGOUT_API_H
#define MBED_ANALOGOUT_API_H
#include "device.h"
#if DEVICE_ANALOGOUT
#ifdef __cplusplus
extern "C" {
#endif
typedef struct dac_s dac_t;
void analogout_init (dac_t *obj, PinName pin);
void analogout_free (dac_t *obj);
void analogout_write (dac_t *obj, float value);
void analogout_write_u16(dac_t *obj, uint16_t value);
float analogout_read (dac_t *obj);
uint16_t analogout_read_u16 (dac_t *obj);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,80 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_CAN_API_H
#define MBED_CAN_API_H
#include "device.h"
#if DEVICE_CAN
#include "PinNames.h"
#include "PeripheralNames.h"
#include "can_helper.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
IRQ_RX,
IRQ_TX,
IRQ_ERROR,
IRQ_OVERRUN,
IRQ_WAKEUP,
IRQ_PASSIVE,
IRQ_ARB,
IRQ_BUS,
IRQ_READY
} CanIrqType;
typedef enum {
MODE_RESET,
MODE_NORMAL,
MODE_SILENT,
MODE_TEST_GLOBAL,
MODE_TEST_LOCAL,
MODE_TEST_SILENT
} CanMode;
typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
typedef struct can_s can_t;
void can_init (can_t *obj, PinName rd, PinName td);
void can_free (can_t *obj);
int can_frequency(can_t *obj, int hz);
void can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id);
void can_irq_free (can_t *obj);
void can_irq_set (can_t *obj, CanIrqType irq, uint32_t enable);
int can_write (can_t *obj, CAN_Message, int cc);
int can_read (can_t *obj, CAN_Message *msg, int handle);
int can_mode (can_t *obj, CanMode mode);
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle);
void can_reset (can_t *obj);
unsigned char can_rderror (can_t *obj);
unsigned char can_tderror (can_t *obj);
void can_monitor (can_t *obj, int silent);
#ifdef __cplusplus
};
#endif
#endif // MBED_CAN_API_H
#endif

View file

@ -0,0 +1,63 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ETHERNET_API_H
#define MBED_ETHERNET_API_H
#include "device.h"
#if DEVICE_ETHERNET
#ifdef __cplusplus
extern "C" {
#endif
// Connection constants
int ethernet_init(void);
void ethernet_free(void);
// write size bytes from data to ethernet buffer
// return num bytes written
// or -1 if size is too big
int ethernet_write(const char *data, int size);
// send ethernet write buffer, returning the packet size sent
int ethernet_send(void);
// recieve from ethernet buffer, returning packet size, or 0 if no packet
int ethernet_receive(void);
// read size bytes in to data, return actual num bytes read (0..size)
// if data == NULL, throw the bytes away
int ethernet_read(char *data, int size);
// get the ethernet address
void ethernet_address(char *mac);
// see if the link is up
int ethernet_link(void);
// force link settings
void ethernet_set_link(int speed, int duplex);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,51 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_API_H
#define MBED_GPIO_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Set the given pin as GPIO
* @param pin The pin to be set as GPIO
* @return The GPIO port mask for this pin
**/
uint32_t gpio_set(PinName pin);
/* GPIO object */
void gpio_init(gpio_t *obj, PinName pin);
void gpio_mode (gpio_t *obj, PinMode mode);
void gpio_dir (gpio_t *obj, PinDirection direction);
void gpio_write(gpio_t *obj, int value);
int gpio_read (gpio_t *obj);
// the following set of functions are generic and are implemented in the common gpio.c file
void gpio_init_in(gpio_t* gpio, PinName pin);
void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode);
void gpio_init_out(gpio_t* gpio, PinName pin);
void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value);
void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,47 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_IRQ_API_H
#define MBED_GPIO_IRQ_API_H
#include "device.h"
#if DEVICE_INTERRUPTIN
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
IRQ_NONE,
IRQ_RISE,
IRQ_FALL
} gpio_irq_event;
typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id);
void gpio_irq_free(gpio_irq_t *obj);
void gpio_irq_set (gpio_irq_t *obj, gpio_irq_event event, uint32_t enable);
void gpio_irq_enable(gpio_irq_t *obj);
void gpio_irq_disable(gpio_irq_t *obj);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_I2C_API_H
#define MBED_I2C_API_H
#include "device.h"
#if DEVICE_I2C
#ifdef __cplusplus
extern "C" {
#endif
typedef struct i2c_s i2c_t;
enum {
I2C_ERROR_NO_SLAVE = -1,
I2C_ERROR_BUS_BUSY = -2
};
void i2c_init (i2c_t *obj, PinName sda, PinName scl);
void i2c_frequency (i2c_t *obj, int hz);
int i2c_start (i2c_t *obj);
int i2c_stop (i2c_t *obj);
int i2c_read (i2c_t *obj, int address, char *data, int length, int stop);
int i2c_write (i2c_t *obj, int address, const char *data, int length, int stop);
void i2c_reset (i2c_t *obj);
int i2c_byte_read (i2c_t *obj, int last);
int i2c_byte_write (i2c_t *obj, int data);
#if DEVICE_I2CSLAVE
void i2c_slave_mode (i2c_t *obj, int enable_slave);
int i2c_slave_receive(i2c_t *obj);
int i2c_slave_read (i2c_t *obj, char *data, int length);
int i2c_slave_write (i2c_t *obj, const char *data, int length);
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,43 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINMAP_H
#define MBED_PINMAP_H
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
int peripheral;
int function;
} PinMap;
void pin_function(PinName pin, int function);
void pin_mode (PinName pin, PinMode mode);
uint32_t pinmap_peripheral(PinName pin, const PinMap* map);
uint32_t pinmap_merge (uint32_t a, uint32_t b);
void pinmap_pinout (PinName pin, const PinMap *map);
uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,42 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PORTMAP_H
#define MBED_PORTMAP_H
#include "device.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
#ifdef __cplusplus
extern "C" {
#endif
typedef struct port_s port_t;
PinName port_pin(PortName port, int pin_n);
void port_init (port_t *obj, PortName port, int mask, PinDirection dir);
void port_mode (port_t *obj, PinMode mode);
void port_dir (port_t *obj, PinDirection dir);
void port_write(port_t *obj, int value);
int port_read (port_t *obj);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,49 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PWMOUT_API_H
#define MBED_PWMOUT_API_H
#include "device.h"
#if DEVICE_PWMOUT
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pwmout_s pwmout_t;
int pwmout_init (pwmout_t* obj, PinName pin); // != 0 - error
void pwmout_free (pwmout_t* obj);
//void pwmout_write (pwmout_t* obj, float percent);
//float pwmout_read (pwmout_t* obj);
//void pwmout_period (pwmout_t* obj, float seconds);
//void pwmout_period_ms (pwmout_t* obj, int ms);
void pwmout_period_us (pwmout_t* obj, uint32_t us);
//void pwmout_pulsewidth (pwmout_t* obj, float seconds);
//void pwmout_pulsewidth_ms(pwmout_t* obj, uint32_t ms);
void pwmout_pulsewidth_us(pwmout_t* obj, uint32_t us);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,42 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_RTC_API_H
#define MBED_RTC_API_H
#include "device.h"
#if DEVICE_RTC
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
void rtc_init(void);
void rtc_free(void);
int rtc_isenabled(void);
time_t rtc_read(void);
void rtc_write(time_t t);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,78 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SERIAL_API_H
#define MBED_SERIAL_API_H
#include "device.h"
#if DEVICE_SERIAL
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ParityNone = 0,
ParityOdd = 1,
ParityEven = 2,
ParityForced1 = 3,
ParityForced0 = 4
} SerialParity;
typedef enum {
RxIrq,
TxIrq
} SerialIrq;
typedef enum {
FlowControlNone,
FlowControlRTS,
FlowControlCTS,
FlowControlRTSCTS
} FlowControl;
typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event);
typedef struct serial_s serial_t;
void serial_init (serial_t *obj, PinName tx, PinName rx);
void serial_free (serial_t *obj);
void serial_baud (serial_t *obj, int baudrate);
void serial_format (serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id);
void serial_irq_set (serial_t *obj, SerialIrq irq, uint32_t enable);
int serial_getc (serial_t *obj);
void serial_putc (serial_t *obj, int c);
int serial_readable (serial_t *obj);
int serial_writable (serial_t *obj);
void serial_clear (serial_t *obj);
void serial_break_set (serial_t *obj);
void serial_break_clear(serial_t *obj);
void serial_pinout_tx(PinName tx);
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,64 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SLEEP_API_H
#define MBED_SLEEP_API_H
#include "device.h"
#if DEVICE_SLEEP
#ifdef __cplusplus
extern "C" {
#endif
/** Send the microcontroller to sleep
*
* The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
* system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
* dynamic power used by the processor, memory systems and buses. The processor, peripheral and
* memory state are maintained, and the peripherals continue to work and can generate interrupts.
*
* The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
*
* @note
* The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
* Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
* able to access the LocalFileSystem
*/
void sleep(void);
/** Send the microcontroller to deep sleep
*
* This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
* has the same sleep features as sleep plus it powers down peripherals and clocks. All state
* is still maintained.
*
* The processor can only be woken up by an external interrupt on a pin or a watchdog timer.
*
* @note
* The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
* Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
* able to access the LocalFileSystem
*/
void deepsleep(void);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,45 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SPI_API_H
#define MBED_SPI_API_H
#include "device.h"
#if DEVICE_SPI
#ifdef __cplusplus
extern "C" {
#endif
typedef struct spi_s spi_t;
void spi_init (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
void spi_free (spi_t *obj);
void spi_format (spi_t *obj, int bits, int mode, int slave);
void spi_frequency (spi_t *obj, int hz);
int spi_master_write (spi_t *obj, int value);
int spi_slave_receive(spi_t *obj);
int spi_slave_read (spi_t *obj);
void spi_slave_write (spi_t *obj, int value);
int spi_busy (spi_t *obj);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,51 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_US_TICKER_API_H
#define MBED_US_TICKER_API_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t timestamp_t;
uint32_t us_ticker_read(void);
typedef void (*ticker_event_handler)(uint32_t id);
void us_ticker_set_handler(ticker_event_handler handler);
typedef struct ticker_event_s {
timestamp_t timestamp;
uint32_t id;
struct ticker_event_s *next;
} ticker_event_t;
void us_ticker_init(void);
void us_ticker_set_interrupt(timestamp_t timestamp);
void us_ticker_disable_interrupt(void);
void us_ticker_clear_interrupt(void);
void us_ticker_irq_handler(void);
void us_ticker_insert_event(ticker_event_t *obj, timestamp_t timestamp, uint32_t id);
void us_ticker_remove_event(ticker_event_t *obj);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,44 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GDMA_API_H
#define MBED_GDMA_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gdma_s {
HAL_GDMA_OBJ gdma_obj;
uint8_t gdma_allocated;
};
typedef struct gdma_s gdma_t;
typedef void (*dma_irq_handler)(uint32_t id);
void dma_memcpy_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id);
void dma_memcpy_deinit(gdma_t *dma_obj);
void dma_memcpy(gdma_t *dma_obj, void *dst, void* src, uint32_t len);
void dma_memcpy_aggr_init(gdma_t * dma_obj, dma_irq_handler handler, uint32_t id);
void dma_memcpy_aggr(gdma_t * dma_obj, PHAL_GDMA_BLOCK block_info);
#ifdef __cplusplus
}
#endif
#endif // end of "#define MBED_GDMA_API_H"

View file

@ -0,0 +1,31 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#ifndef MBED_EXT_EFUSE_API_EXT_H
#define MBED_EXT_EFUSE_API_EXT_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
int efuse_get_remaining_length(void);
void efuse_mtp_read(uint8_t * data);
int efuse_mtp_write(uint8_t *data, uint8_t len);
int efuse_otp_read(u8 address, u8 len, u8 *buf);
int efuse_otp_write(u8 address, u8 len, u8 *buf);
int efuse_disable_jtag(void);
#ifdef __cplusplus
}
#endif
#endif // MBED_EXT_EFUSE_API_EXT_H

View file

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ETHERNET_EX_API_H
#define ETHERNET_EX_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ETH_TX_DESC_SIZE 20 // 20 Bytes
#define ETH_RX_DESC_SIZE 16 // 16 Bytes
#define ETH_PKT_BUF_SIZE 1536
typedef void (*ethernet_callback)(uint32_t event, uint32_t data);
void ethernet_irq_hook(ethernet_callback callback);
/* Set the numbers of Tx/Rx descriptor */
void ethernet_set_descnum(uint8_t txdescCnt, uint8_t rxdescCnt);
/* Set the start address of Tx/Rx descriptor and packet buffer */
void ethernet_trx_pre_setting(uint8_t *TxDescAddr, uint8_t *RxDescAddr, uint8_t *pTxPktBuf, uint8_t *pRxPktBuf);
#ifdef __cplusplus
}
#endif
#endif // #ifndef ETHERNET_EX_API_H

View file

@ -0,0 +1,49 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EX_API_H
#define EX_API_H
#include "device.h"
#include "serial_api.h"
#include "spi_api.h"
#include "dma_api.h"
#include "flash_api.h"
#include "flash_eep.h"
#include "gpio_ex_api.h"
#include "gpio_irq_ex_api.h"
#include "i2c_ex_api.h"
#include "i2s_api.h"
#include "nfc_api.h"
#include "serial_ex_api.h"
#include "sleep_ex_api.h"
#include "spi_ex_api.h"
#include "sys_api.h"
#include "wdt_api.h"
#include "ethernet_ex_api.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,55 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#ifndef MBED_EXT_FLASH_API_EXT_H
#define MBED_EXT_FLASH_API_EXT_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct flash_s flash_t;
/**
* global data structure
*/
extern flash_t flashobj;
extern bool fspic_isinit;
enum {
FLASH_COMPLETE = 0,
FLASH_ERROR_2 = 1,
};
void flash_turnon (void);
void flash_init (flash_t *obj);
void flash_erase_sector (flash_t *obj, uint32_t address);
void flash_erase_block (flash_t *obj, uint32_t address);
int flash_read_word (flash_t *obj, uint32_t address, uint32_t * data);
int flash_write_word (flash_t *obj, uint32_t address, uint32_t data);
int flash_stream_read (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
int flash_stream_write (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
void flash_write_protect (flash_t *obj, uint32_t protect);
int flash_get_status (flash_t * obj);
int flash_set_status (flash_t * obj, uint32_t data);
void flash_reset_status (flash_t * obj);
int flash_burst_write (flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data);
int flash_burst_read (flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data);
int flash_set_extend_addr (flash_t * obj, uint32_t data);
int flash_get_extend_addr (flash_t * obj);
unsigned int flash_get_size (flash_t *obj);
int flash_otp_read (flash_t *obj, uint32_t address, uint32_t Length, uint8_t * data);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,52 @@
/******************************************************************************
* FileName: flash_eep.h
* Description: FLASH
* Alternate SDK
* Author: PV`
* (c) PV` 2015
*******************************************************************************/
#ifndef __FLASH_EEP_H_
#define __FLASH_EEP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <basic_types.h>
#include <FreeRTOS.h>
#include <queue.h>
//-----------------------------------------------------------------------------
#ifndef FLASH_SECTOR_SIZE
#define FLASH_SECTOR_SIZE 4096
#endif
#define FLASH_SECTORS 256 // 1 Mbytes
#define FLASH_CHIP_SIZE (FLASH_SECTORS * FLASH_SECTOR_SIZE)
#define FMEMORY_SCFG_BANK_SIZE FLASH_SECTOR_SIZE // размер сектора, 4096 bytes
#define FMEMORY_SCFG_BANKS 2 // кол-во секторов для работы 2...
#define FMEMORY_SCFG_BASE_ADDR (FLASH_CHIP_SIZE - (FMEMORY_SCFG_BANKS*FMEMORY_SCFG_BANK_SIZE)) // = 0xFE000
//-----------------------------------------------------------------------------
#define FLASH_EEP_ATTR
//-----------------------------------------------------------------------------
enum eFMEMORY_ERRORS {
FMEM_NOT_FOUND = -1, // -1 - не найден
FMEM_FLASH_ERR = -2, // -2 - flash rd/wr/erase error
FMEM_ERROR = -3, // -3 - error
FMEM_OVR_ERR = -4, // -4 - переполнение FMEMORY_SCFG_BANK_SIZE
FMEM_MEM_ERR = -5 // -5 - heap alloc error
};
//-----------------------------------------------------------------------------
// extern QueueHandle_t flash_mutex;
signed short flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize) FLASH_EEP_ATTR; // возврат: размер объекта последнего сохранения, -1 - не найден, -2 - error
bool flash_write_cfg(void *ptr, unsigned short id, unsigned short size) FLASH_EEP_ATTR;
//-----------------------------------------------------------------------------
#ifndef USE_FLASH_EEP
#define USE_FLASH_EEP 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* __FLASH_EEP_H_ */

View file

@ -0,0 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_API_H
#define MBED_GPIO_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
/* GPIO object */
void gpio_direct_write(gpio_t *obj, BOOL value) ;
void gpio_pull_ctrl(gpio_t *obj, PinMode pull_type);
void gpio_deinit(gpio_t *obj, PinName pin);
void gpio_change_dir(gpio_t *obj, PinDirection direction);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,40 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_IRQ_EX_API_H
#define MBED_GPIO_IRQ_EX_API_H
#include "device.h"
#if DEVICE_INTERRUPTIN
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
IRQ_LOW = 3,
IRQ_HIGH =4
} gpio_irq_event_ex;
void gpio_irq_deinit(gpio_irq_t *obj);
void gpio_irq_pull_ctrl(gpio_irq_t *obj, PinMode pull_type);
#ifdef __cplusplus
}
#endif
#endif // end of "#if DEVICE_INTERRUPTIN"
#endif // end of #ifndef MBED_GPIO_IRQ_EX_API_H

View file

@ -0,0 +1,46 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef I2C_EX_API_H
#define I2C_EX_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
I2C_TX_COMPLETE = 0,
I2C_RX_COMPLETE = 1,
I2C_RD_REQ_COMMAND = 2,
I2C_ERR_OCCURRED = 3,
}I2CCallback;
void i2c_set_user_callback(i2c_t *obj, I2CCallback i2ccb, void(*i2c_callback)(void *));
void i2c_clear_user_callback(i2c_t *obj, I2CCallback i2ccb);
int i2c_enable_control(i2c_t *obj, int enable);
void i2c_restart_enable(i2c_t *obj);
void i2c_restart_disable(i2c_t *obj);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,76 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#ifndef MBED_EXT_I2S_API_EXT_H
#define MBED_EXT_I2S_API_EXT_H
#include "device.h"
#include "rtl8195a.h"
#include "hal_i2s.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
SR_8KHZ = I2S_SR_8KHZ,
SR_16KHZ = I2S_SR_16KHZ,
SR_24KHZ = I2S_SR_24KHZ,
SR_32KHZ = I2S_SR_32KHZ,
SR_48KHZ = I2S_SR_48KHZ,
SR_96KHZ = I2S_SR_96KHZ,
SR_7p35KHZ = I2S_SR_7p35KHZ,
SR_11p02KHZ = I2S_SR_11p02KHZ,
SR_22p05KHZ = I2S_SR_22p05KHZ,
SR_29p4KHZ = I2S_SR_29p4KHZ,
SR_44p1KHZ = I2S_SR_44p1KHZ,
SR_88p2KHZ = I2S_SR_88p2KHZ
};
enum {
CH_STEREO = I2S_CH_STEREO,
CH_MONO = I2S_CH_MONO
};
enum {
WL_16b = I2S_WL_16,
WL_24b = I2S_WL_24
};
enum {
I2S_DIR_RX = I2S_ONLY_RX, // Rx Only
I2S_DIR_TX = I2S_ONLY_TX, // Tx Only
I2S_DIR_TXRX = I2S_TXRX // Tx & Rx (BiDirection)
};
typedef void (*i2s_irq_handler)(uint32_t id, char *pbuf);
typedef struct i2s_s i2s_t;
void i2s_init(i2s_t *obj, PinName sck, PinName ws, PinName sd);
void i2s_set_dma_buffer(i2s_t *obj, char *tx_buf, char *rx_buf,
uint32_t page_num, uint32_t page_size);
void i2s_tx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id);
void i2s_rx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id);
void i2s_set_direction(i2s_t *obj, int trx_type);
void i2s_set_param(i2s_t *obj, int channel_num, int rate, int word_len);
void i2s_deinit(i2s_t *obj);
int* i2s_get_tx_page(i2s_t *obj);
void i2s_send_page(i2s_t *obj, uint32_t *pbuf);
void i2s_recv_page(i2s_t *obj);
void i2s_enable(i2s_t *obj);
void i2s_disable(i2s_t *obj);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,66 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_UART_API_H
#define LOG_UART_API_H
#include "device.h"
#include "serial_api.h"
#include "hal_log_uart.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*loguart_irq_handler)(uint32_t id, LOG_UART_INT_ID event);
typedef struct log_uart_s log_uart_t;
int32_t log_uart_init (log_uart_t *obj, int baudrate, int data_bits, SerialParity parity, int stop_bits);
void log_uart_free(log_uart_t *obj);
void log_uart_baud(log_uart_t *obj, int baudrate);
void log_uart_format(log_uart_t *obj, int data_bits, SerialParity parity, int stop_bits);
void log_uart_irq_handler(log_uart_t *obj, loguart_irq_handler handler, uint32_t id);
void log_uart_irq_set(log_uart_t *obj, LOG_UART_INT_ID irq, uint32_t enable);
char log_uart_getc(log_uart_t *obj);
void log_uart_putc(log_uart_t *obj, char c);
int log_uart_readable(log_uart_t *obj);
int log_uart_writable(log_uart_t *obj);
void log_uart_clear(log_uart_t *obj);
void log_uart_clear_tx(log_uart_t *obj);
void log_uart_clear_rx(log_uart_t *obj);
void log_uart_break_set(log_uart_t *obj);
void log_uart_break_clear(log_uart_t *obj);
void log_uart_tx_comp_handler(log_uart_t *obj, void *handler, uint32_t id);
void log_uart_rx_comp_handler(log_uart_t *obj, void *handler, uint32_t id);
void log_uart_line_status_handler(log_uart_t *obj, void *handler, uint32_t id);
int32_t log_uart_recv (log_uart_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms);
int32_t log_uart_send (log_uart_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms);
int32_t log_uart_recv_stream (log_uart_t *obj, char *prxbuf, uint32_t len);
int32_t log_uart_send_stream (log_uart_t *obj, char *ptxbuf, uint32_t len);
int32_t log_uart_recv_stream_timeout (log_uart_t *obj, char *prxbuf, uint32_t len,
uint32_t timeout_ms, void *force_cs);
int32_t log_uart_send_stream_abort (log_uart_t *obj);
int32_t log_uart_recv_stream_abort (log_uart_t *obj);
void log_uart_disable (log_uart_t *obj);
void log_uart_enable (log_uart_t *obj);
uint8_t log_uart_raed_lsr(log_uart_t *obj);
uint8_t log_uart_raed_msr(log_uart_t *obj);
#ifdef __cplusplus
}
#endif
#endif // end of "#ifndef LOG_UART_API_H"

View file

@ -0,0 +1,70 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_NFC_API_H
#define MBED_NFC_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NFCTAGLENGTH 36 // maximum 36*4=144 bytes
#define NFC_MAX_CACHE_PAGE_NUM 36 // maximum 36*4=144 bytes
typedef enum _NFC_STATUS_ {
NFC_OK = 0,
NFC_ERROR = -1
}NFC_STATUS, *PNFC_STATUS;
typedef enum _NFC_PWR_STATUS_ {
NFC_PWR_DISABLE = 0,
NFC_PWR_RUNNING = 1,
NFC_PWR_SLEEP0 = 2,
NFC_PWR_SLEEP1 = 3,
NFC_PWR_DOWN = 4,
NFC_PWR_ERROR = -1
}NFC_PWR_STATUS, *PNFC_PWR_STATUS;
typedef enum _NFC_EVENT_ {
NFC_EV_READER_PRESENT = (1<<0),
NFC_EV_READ = (1<<1),
NFC_EV_WRITE = (1<<2),
NFC_EV_ERR = (1<<3),
NFC_EV_CACHE_READ = (1<<4)
}NFC_EVENT, *PNFC_EVENT;
typedef struct nfctag_s nfctag_t;
typedef void (*nfc_read_cb)(void *arg, void *buf, unsigned int page);
typedef void(*nfc_write_cb)(void *arg, unsigned int page, uint32_t pgdat);
typedef void(*nfc_event_cb)(void *arg, unsigned int event);
typedef void(*nfc_cache_read_cb)(void *arg, void *buf, unsigned int page);
int nfc_init(nfctag_t *obj, uint32_t *pg_init_val);
void nfc_read(nfctag_t *obj, nfc_read_cb handler, void *arg);
void nfc_write(nfctag_t *obj, nfc_write_cb handler, void *arg);
void nfc_event(nfctag_t *obj, nfc_event_cb handler, void *arg, unsigned int event_mask);
int nfc_power(nfctag_t *obj, int pwr_mode, int wake_event);
int nfc_cache_write(nfctag_t *obj, uint32_t *tbuf, unsigned int spage, unsigned int pg_num);
int nfc_cache_raed(nfctag_t *obj, nfc_cache_read_cb handler, void *arg, unsigned int start_pg);
int nfc_status(nfctag_t *obj);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,60 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SERIAL_EX_API_H
#define MBED_SERIAL_EX_API_H
#include "device.h"
#if DEVICE_SERIAL
#ifdef __cplusplus
extern "C" {
#endif
// Define RX FIFO Level: RX interrupt trigger, RTS de-assert trigger
typedef enum {
FifoLv1Byte=0, // 1-byte
FifoLvQuarter=1, // 4-byte
FifoLvHalf=2, // 8-byte
FifoLvFull=3 // 14-byte
} SerialFifoLevel;
void serial_clear_tx(serial_t *obj);
void serial_clear_rx(serial_t *obj);
void serial_send_comp_handler(serial_t *obj, void *handler, uint32_t id);
void serial_recv_comp_handler(serial_t *obj, void *handler, uint32_t id);
int32_t serial_recv_blocked (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms);
int32_t serial_send_blocked (serial_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms);
int32_t serial_recv_stream (serial_t *obj, char *prxbuf, uint32_t len);
int32_t serial_send_stream (serial_t *obj, char *ptxbuf, uint32_t len);
int32_t serial_recv_stream_dma (serial_t *obj, char *prxbuf, uint32_t len);
int32_t serial_send_stream_dma (serial_t *obj, char *ptxbuf, uint32_t len);
int32_t serial_send_stream_abort (serial_t *obj);
int32_t serial_recv_stream_abort (serial_t *obj);
void serial_disable (serial_t *obj);
void serial_enable (serial_t *obj);
int32_t serial_recv_stream_timeout (serial_t *obj, char *prxbuf, uint32_t \
len, uint32_t timeout_ms, void *force_cs);
int32_t serial_recv_stream_dma_timeout (serial_t *obj, char *prxbuf, \
uint32_t len, uint32_t timeout_ms, void *force_cs);
#ifdef __cplusplus
}
#endif
#endif
#endif // #ifndef MBED_SERIAL_EX_API_H

View file

@ -0,0 +1,98 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SLEEP_EX_API_H
#define MBED_SLEEP_EX_API_H
#include "device.h"
#if DEVICE_SLEEP
#ifdef __cplusplus
extern "C" {
#endif
/* Sleep Eake Up event, the User application also
need to config the peripheral to trigger wake up event */
#define SLEEP_WAKEUP_BY_STIMER (SLP_STIMER) // wake up by system timer
#define SLEEP_WAKEUP_BY_GTIMER (SLP_GTIMER) // wake up by General purpose timer timeout
#define SLEEP_WAKEUP_BY_GPIO_INT (SLP_GPIO) // wake up by GPIO Port A[7:0] Interrupt
#define SLEEP_WAKEUP_BY_WLAN (SLP_WL) // wake up by WLan event
#define SLEEP_WAKEUP_BY_NFC (SLP_NFC) // wake up by NFC event
#define SLEEP_WAKEUP_BY_SDIO (SLP_SDIO) // wake up by SDIO event
#define SLEEP_WAKEUP_BY_USB (SLP_USB) // wake up by USB event
// Deep Standby Wakeup event
#define STANDBY_WAKEUP_BY_STIMER (BIT0) // wake up by system timer
#define STANDBY_WAKEUP_BY_NFC (BIT1) // wake up by NFC event
//#define SLEEP_WAKEUP_BY_DS_TIMER (BIT2) // The timer to wakeup from Deep Sleep timer
// Do not modify these definition, or need to modify the code also.
#define STANDBY_WAKEUP_BY_PA5 (BIT4) // GPIO Port A[5]
#define STANDBY_WAKEUP_BY_PC7 (BIT5) // GPIO Port C[7]
#define STANDBY_WAKEUP_BY_PD5 (BIT6) // GPIO Port D[5]
#define STANDBY_WAKEUP_BY_PE3 (BIT7) // GPIO Port E[3]
// Deep Sleep Wakeup event
#define DSLEEP_WAKEUP_BY_TIMER (DS_TIMER33)
#define DSLEEP_WAKEUP_BY_GPIO (DS_GPIO) // GPIO Port B[1]
typedef struct _SLEEP_WKUP_EVENT_ {
u8 wakeup_event; // Wake up event: Timer, NFC, GPIO
u8 gpio_option; // GPIO Wakeup setting: [3:0]: Pin 3~0 enable, [7:4]: pin3~0 active high/low
u32 timer_duration; // the sleep duration and then wakeup
} SLEEP_WAKEUP_EVENT, *PSLEEP_WAKEUP_EVENT;
/** Send the microcontroller to sleep
*
* The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
* system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
* dynamic power used by the processor, memory systems and buses. The processor, peripheral and
* memory state are maintained, and the peripherals continue to work and can generate interrupts.
*
* The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
*
* @note
* The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
* Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
* able to access the LocalFileSystem
*/
void sleep_ex(uint32_t wakeup_event, uint32_t sleep_duration);
void sleep_ex_selective(uint32_t wakeup_event, uint32_t sleep_duration, uint32_t clk_sourec_enable, uint32_t sdr_enable);
void standby_wakeup_event_add(uint32_t wakeup_event, uint32_t sleep_duration_ms, uint32_t gpio_active);
void standby_wakeup_event_del(uint32_t wakeup_event);
void deepstandby_ex(void);
/** Send the microcontroller to deep sleep
*
* This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
* has the same sleep features as sleep plus it powers down peripherals and clocks. All state
* is still maintained.
*
* The processor can only be woken up by an external interrupt on a pin or a timer.
*
* @note
* The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
* Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
* able to access the LocalFileSystem
*/
void deepsleep_ex(uint32_t wakeup_event, uint32_t sleep_duration);
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,115 @@
#ifndef __SPDIO_API_H__
#define __SPDIO_API_H__
#include <osdep_service.h>
#define SPDIO_API_DBG
#ifdef SPDIO_API_DBG
#define SPDIO_API_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _SPDIO_API_PRINTK(fmt, args...) printf(fmt,## args)
#else
#define SPDIO_API_PRINTK(fmt, args...)
#define _SPDIO_API_PRINTK(fmt, args...)
#endif
#define SPDIO_DMA_ALIGN_4 4
#define SPDIO_RX_BUFSZ_ALIGN(x) ((((x-1)>>6)+1)<<6) //alignement to 64
#define SPDIO_RXDESC_SZ 24
/*Don't modify this enum table*/
enum spdio_rx_data_t{
SPDIO_RX_DATA_NULL = 0x00,
SPDIO_RX_DATA_ETH = 0x83, //an ethernet packet received
SPDIO_RX_DATA_ATCMD = 0x11, //an AT command packet received
SPDIO_RX_DATA_USER = 0x41, //defined by user
};
enum spdio_tx_data_t{
SPDIO_TX_DATA_NULL = 0x00,
SPDIO_TX_DATA_ETH = 0x82, //an ethernet packet sent
SPDIO_TX_DATA_ATCMDRSP = 0x10, //an AT command response packet sent
SPDIO_TX_DATA_USER = 0x40, // defined by user
};
struct spdio_buf_t{
void *priv; //priv data from user
u32 buf_allocated; //The spdio buffer allocated address
u16 size_allocated; //The actual allocated size
u32 buf_addr; //The spdio buffer physical address, it must be 4-bytes aligned
u16 buf_size;
u8 type; //The type of the data which this buffer carries, spdio_rx_data_t and spdio_tx_data_t
u8 reserved;
};
struct spdio_t {
void *priv; //not used by user
u32 tx_bd_num; //for spdio send data to host, 2 bd for one packet, so this value must be rounded to 2
u32 rx_bd_num; //for spdio receive data from host
u32 rx_bd_bufsz; //buffer size = desired packet length + 24(spdio header info), must be rounded to 64
struct spdio_buf_t *rx_buf; //buffer array for spdio receive assigned by user, rx_bd_bufsz * rx_bd_num
/**
*@brief: rx_done_cb: pointer to callback function defined by user,
called by spdio when one packet receive done
*@param priv: a pointer to spdio_t structure which is used to initilize spdio interface
*@param pbuf: a pointer to spdio_buf_t structure which is spdio receive buffer
*@param pdata: the actual received packet payload
*@param size: the actual payload length
*@param type: the received packet type, spdio_rx_data_t
*@retval: SUCCESS or FAIL
*/
char (*rx_done_cb)(void *priv, void* pbuf, u8 *pdata, u16 size, u8 type);
/**
*@brief: tx_done_cb: pointer to callback function defined by user,
called by spdio when one packet sent done
*@param priv: a pointer to spdio_t structure which is used to initilize spdio interface
*@param pbuf: a pointer to spdio_buf_t structure which carries the transmit packet
*@retval: SUCCESS or FAIL
*/
char (*tx_done_cb)(void *priv, void* pbuf);
};
/**
* @brief Gets example setting for spdio obj.
* @param obj: a pointer to an spdio_t structure which will be initialized with an example settings
* @retval None
*/
void spdio_structinit(struct spdio_t *obj);
/**
* @brief Initialize spdio interface.
* @param obj, a pointer to a spdio_t structure which should be initialized by user,
* and which will be used to initialize spdio interface
* obj->tx_bd_num: spdio write bd number, needs 2 bd for one transaction
* obj->rx_bd_num: spdio read bd number
* obj->rx_bd_bufsz: spdio read buffer size
* obj->rx_buf: spdio read buffer array
* @retval None
*/
void spdio_init(struct spdio_t *obj);
/**
* @brief Deinitialize spdio interface.
* @param obj: a pointer to spdio_t structure which is already initialized
* @retval None
*/
void spdio_deinit(struct spdio_t *obj);
/**
* @brief spdio write function.
* @param obj: a pointer to spdio_t structure which is already initialized
* @param pbuf: a pointer to spdio_buf_t structure which carries the payload
* @retval SUCCESS or FAIL
*/
s8 spdio_tx(struct spdio_t *obj, struct spdio_buf_t *pbuf);
/**
* @brief an obj which will be used to initialize sdio interface
* so it must be initialized before calling HalSdioInit();
*/
extern struct spdio_t *g_spdio_priv;
#endif //#ifndef __SPDIO_API_H__

View file

@ -0,0 +1,94 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SPI_EXT_API_H
#define MBED_SPI_EXT_API_H
#include "device.h"
#if DEVICE_SPI
#ifdef __cplusplus
extern "C" {
#endif
#define SPI_DMA_RX_EN (1<<0)
#define SPI_DMA_TX_EN (1<<1)
enum {
SPI_SCLK_IDLE_LOW=0, // the SCLK is Low when SPI is inactive
SPI_SCLK_IDLE_HIGH=2 // the SCLK is High when SPI is inactive
};
// SPI Master mode: for continuous transfer, how the CS toggle:
enum {
SPI_CS_TOGGLE_EVERY_FRAME=0, // let SCPH=0 then the CS toggle every frame
SPI_CS_TOGGLE_START_STOP=1 // let SCPH=1 the CS toggle at start and stop
};
enum {
SPI_SCLK_TOGGLE_MIDDLE=0, // Serial Clk toggle at middle of 1st data bit and latch data at 1st Clk edge
SPI_SCLK_TOGGLE_START=1 // Serial Clk toggle at start of 1st data bit and latch data at 2nd Clk edge
};
typedef enum {
CS_0 = 0,
CS_1 = 1,
CS_2 = 2,
CS_3 = 3,
CS_4 = 4,
CS_5 = 5,
CS_6 = 6,
CS_7 = 7
}ChipSelect;
#define SPI_STATE_READY 0x00
#define SPI_STATE_RX_BUSY (1<<1)
#define SPI_STATE_TX_BUSY (1<<2)
typedef enum {
SpiRxIrq,
SpiTxIrq
} SpiIrq;
typedef void (*spi_irq_handler)(uint32_t id, SpiIrq event);
void spi_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id);
void spi_bus_tx_done_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id);
int32_t spi_slave_read_stream(spi_t *obj, char *rx_buffer, uint32_t length);
int32_t spi_slave_write_stream(spi_t *obj, char *tx_buffer, uint32_t length);
int32_t spi_master_read_stream(spi_t *obj, char *rx_buffer, uint32_t length);
int32_t spi_master_write_stream(spi_t *obj, char *tx_buffer, uint32_t length);
int32_t spi_master_write_read_stream(spi_t *obj, char *tx_buffer,
char *rx_buffer, uint32_t length);
int32_t spi_slave_read_stream_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms);
#ifdef CONFIG_GDMA_EN
int32_t spi_slave_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length);
int32_t spi_slave_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length);
int32_t spi_master_write_read_stream_dma(spi_t * obj, char * tx_buffer, char * rx_buffer, uint32_t length);
int32_t spi_master_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length);
int32_t spi_master_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length);
int32_t spi_slave_read_stream_dma_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,52 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SYS_API_H
#define MBED_SYS_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Turn off the JTAG function
*
* @return None
*
*/
void sys_jtag_off(void);
void sys_clear_ota_signature(void);
void sys_recover_ota_signature(void);
void sys_log_uart_on(void);
void sys_log_uart_off(void);
void sys_adc_calibration(u8 write, u16 *offset, u16 *gain);
u8 sys_is_sdram_power_on(void);
void sys_sdram_off(void);
/**
* @brief system software reset
*
* @return None
*
*/
void sys_reset(void);
#ifdef __cplusplus
}
#endif
#endif // MBED_SYS_API_H

View file

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_WATCHDOG_API_H
#define MBED_WATCHDOG_API_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*wdt_irq_handler)(uint32_t id);
/** Initial the watch dog time setting
*
* This function will initial and enable the watchdog timer with a given timeout value.
* When the watchdog timer timeout event is triggered, the system will be reset. User also can
* register a callback function to handle the watchdog timer timeout event.
*/
void watchdog_init(uint32_t timeout_ms);
/** Start the watchdog counting
*
* This function will active the watchdog timer down counting. When the watchdog timer count down
* to 0, a callback function will be called or the system will be reset.
*/
void watchdog_start(void);
/** Stop the watchdog counting
*
* This function will stop the watchdog timer down counting. If a user application aware a
* procedure may takes too long and cause the watchdog timer timeout, the application use this
* function to stop the watchdog timer to prevent the watchdog timer timeout.
*/
void watchdog_stop(void);
/** Refresh the watchdog counting
*
* This function will reload the watchdog timer counting value. Usually a application do the watchdog
* timer reflash in the main loop to prevent the watchdog timer timeout.
*/
void watchdog_refresh(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,14 @@
/* mbed Microcontroller Library - CMSIS
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* A generic CMSIS include header, pulling in RTL8195A specifics
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include <platform/platform_stdlib.h>
#include <hal_platform.h>
#endif

View file

@ -0,0 +1,100 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#if 0
typedef enum {
UART_1 = (int)USART1_BASE,
UART_2 = (int)USART2_BASE,
UART_3 = (int)USART3_BASE,
UART_4 = (int)UART4_BASE,
UART_5 = (int)UART5_BASE,
UART_6 = (int)USART6_BASE
} UARTName;
typedef enum {
ADC0_0 = 0,
ADC0_1,
ADC0_2,
ADC0_3,
ADC0_4,
ADC0_5,
ADC0_6,
ADC0_7,
ADC0_8,
ADC0_9,
ADC0_10,
ADC0_11,
ADC0_12,
ADC0_13,
ADC0_14,
ADC0_15
} ADCName;
typedef enum {
DAC_0 = 0,
DAC_1
} DACName;
typedef enum {
SPI_1 = (int)SPI1_BASE,
SPI_2 = (int)SPI2_BASE,
SPI_3 = (int)SPI3_BASE,
} SPIName;
typedef enum {
I2C_1 = (int)I2C1_BASE,
I2C_2 = (int)I2C2_BASE,
I2C_3 = (int)I2C3_BASE
} I2CName;
typedef enum {
PWM_1 = 1,
PWM_2,
PWM_3,
PWM_4,
PWM_5,
PWM_6
} PWMName;
typedef enum {
CAN_1 = (int)CAN1_BASE,
CAN_2 = (int)CAN2_BASE
} CANName;
#endif
#define STDIO_UART_TX PA_6
#define STDIO_UART_RX PA_7
#define STDIO_UART UART0
typedef enum {
DAC_0 = 0,
DAC_1
} DACName;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,215 @@
#ifndef _PINNAMES_H_
#define _PINNAMES_H_
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PORT_A = 0,
PORT_B = 1,
PORT_C = 2,
PORT_D = 3,
PORT_E = 4,
PORT_F = 5,
PORT_G = 6,
PORT_H = 7,
PORT_I = 8,
PORT_J = 9,
PORT_K = 10,
PORT_V = 11,
PORT_U = 12,
PORT_MAX
} GPIO_PORT;
#define RTL_PIN_PERI(FUN, IDX, SEL) ((int)(((FUN) << 8) | ((IDX)<<4) | (SEL)))
#define RTL_PIN_FUNC(FUN, SEL) ((int)(((FUN) << 7) | (SEL)))
#define RTL_GET_PERI_SEL(peri) ((int)((peri)&0x0F))
#define RTL_GET_PERI_IDX(peri) ((int)(((peri) >> 4)&0x0F))
typedef enum {
PIN_INPUT=0,
PIN_OUTPUT
} PinDirection;
typedef enum {
PA_0 = (PORT_A<<4|0),
PA_1 = (PORT_A<<4|1),
PA_2 = (PORT_A<<4|2),
PA_3 = (PORT_A<<4|3),
PA_4 = (PORT_A<<4|4),
PA_5 = (PORT_A<<4|5),
PA_6 = (PORT_A<<4|6),
PA_7 = (PORT_A<<4|7),
PB_0 = (PORT_B<<4|0),
PB_1 = (PORT_B<<4|1),
PB_2 = (PORT_B<<4|2),
PB_3 = (PORT_B<<4|3),
PB_4 = (PORT_B<<4|4),
PB_5 = (PORT_B<<4|5),
PB_6 = (PORT_B<<4|6),
PB_7 = (PORT_B<<4|7),
PC_0 = (PORT_C<<4|0),
PC_1 = (PORT_C<<4|1),
PC_2 = (PORT_C<<4|2),
PC_3 = (PORT_C<<4|3),
PC_4 = (PORT_C<<4|4),
PC_5 = (PORT_C<<4|5),
PC_6 = (PORT_C<<4|6),
PC_7 = (PORT_C<<4|7),
PC_8 = (PORT_C<<4|8),
PC_9 = (PORT_C<<4|9),
PD_0 = (PORT_D<<4|0),
PD_1 = (PORT_D<<4|1),
PD_2 = (PORT_D<<4|2),
PD_3 = (PORT_D<<4|3),
PD_4 = (PORT_D<<4|4),
PD_5 = (PORT_D<<4|5),
PD_6 = (PORT_D<<4|6),
PD_7 = (PORT_D<<4|7),
PD_8 = (PORT_D<<4|8),
PD_9 = (PORT_D<<4|9),
PE_0 = (PORT_E<<4|0),
PE_1 = (PORT_E<<4|1),
PE_2 = (PORT_E<<4|2),
PE_3 = (PORT_E<<4|3),
PE_4 = (PORT_E<<4|4),
PE_5 = (PORT_E<<4|5),
PE_6 = (PORT_E<<4|6),
PE_7 = (PORT_E<<4|7),
PE_8 = (PORT_E<<4|8),
PE_9 = (PORT_E<<4|9),
PE_A = (PORT_E<<4|10),
PF_0 = (PORT_F<<4|0),
PF_1 = (PORT_F<<4|1),
PF_2 = (PORT_F<<4|2),
PF_3 = (PORT_F<<4|3),
PF_4 = (PORT_F<<4|4),
PF_5 = (PORT_F<<4|5),
// PF_6 = (PORT_F<<4|6),
// PF_7 = (PORT_F<<4|7),
PG_0 = (PORT_G<<4|0),
PG_1 = (PORT_G<<4|1),
PG_2 = (PORT_G<<4|2),
PG_3 = (PORT_G<<4|3),
PG_4 = (PORT_G<<4|4),
PG_5 = (PORT_G<<4|5),
PG_6 = (PORT_G<<4|6),
PG_7 = (PORT_G<<4|7),
PH_0 = (PORT_H<<4|0),
PH_1 = (PORT_H<<4|1),
PH_2 = (PORT_H<<4|2),
PH_3 = (PORT_H<<4|3),
PH_4 = (PORT_H<<4|4),
PH_5 = (PORT_H<<4|5),
PH_6 = (PORT_H<<4|6),
PH_7 = (PORT_H<<4|7),
PI_0 = (PORT_I<<4|0),
PI_1 = (PORT_I<<4|1),
PI_2 = (PORT_I<<4|2),
PI_3 = (PORT_I<<4|3),
PI_4 = (PORT_I<<4|4),
PI_5 = (PORT_I<<4|5),
PI_6 = (PORT_I<<4|6),
PI_7 = (PORT_I<<4|7),
PJ_0 = (PORT_J<<4|0),
PJ_1 = (PORT_J<<4|1),
PJ_2 = (PORT_J<<4|2),
PJ_3 = (PORT_J<<4|3),
PJ_4 = (PORT_J<<4|4),
PJ_5 = (PORT_J<<4|5),
PJ_6 = (PORT_J<<4|6),
// PJ_7 = (PORT_J<<4|7),
PK_0 = (PORT_K<<4|0),
PK_1 = (PORT_K<<4|1),
PK_2 = (PORT_K<<4|2),
PK_3 = (PORT_K<<4|3),
PK_4 = (PORT_K<<4|4),
PK_5 = (PORT_K<<4|5),
PK_6 = (PORT_K<<4|6),
// PK_7 = (PORT_K<<4|7),
AD_1 = (PORT_V<<4|1),
AD_2 = (PORT_V<<4|2),
AD_3 = (PORT_V<<4|3),
DA_0 = (PORT_U<<4|0),
DA_1 = (PORT_U<<4|1),
// Arduino connector namings
/*
A0 = PA_0,
A1 = PA_1,
A2 = PA_4,
A3 = PB_0,
A4 = PC_1,
A5 = PC_0,
D0 = PA_3,
D1 = PA_2,
D2 = PA_10,
D3 = PB_3,
D4 = PB_5,
D5 = PB_4,
D6 = PB_10,
D7 = PA_8,
D8 = PA_9,
D9 = PC_7,
D10 = PB_6,
D11 = PA_7,
D12 = PA_6,
D13 = PA_5,
D14 = PB_9,
D15 = PB_8,
// Generic signals namings
LED1 = PB_4,
LED2 = PB_5,
LED3 = PB_6,
LED4 = PB_7,
USER_BUTTON = PA_3,
SERIAL_TX = PA_7,
SERIAL_RX = PA_6,
USBTX = PA_7,
USBRX = PA_6,
I2C_SCL = PC_5,
I2C_SDA = PC_4,
SPI_MOSI = PC_2,
SPI_MISO = PC_3,
SPI_SCK = PC_1,
SPI_CS = PC_0,
PWM_OUT = PD_4,
*/
// Not connected
NC = (uint32_t)0xFFFFFFFF
} PinName;
typedef enum {
PullNone = 0,
PullUp = 1,
PullDown = 2,
OpenDrain = 3,
PullDefault = PullNone
} PinMode;
#define PORT_NUM(pin) (((uint32_t)(pin) >> 4) & 0xF)
#define PIN_NUM(pin) ((uint32_t)(pin) & 0xF)
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,38 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PortA = 0,
PortB = 1,
PortC = 2,
PortD = 3,
PortE = 4,
PortF = 5,
PortG = 6,
PortH = 7,
PortI = 8
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,205 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "PinNames.h"
#include "hal_adc.h"
#include "analogin_api.h"
#if CONFIG_ADC_EN
//#include "cmsis.h"
#include "pinmap.h"
extern u32 ConfigDebugErr;
extern u32 ConfigDebuginfo;
void analogin_init (analogin_t *obj, PinName pin){
uint32_t adc_idx;
PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL;
PSAL_ADC_USERCB_ADPT pSalADCUserCBAdpt = NULL;
PSAL_ADC_HND pSalADCHND = NULL;
HAL_ADC_INIT_DAT HalADCInitDataTmp;
PHAL_ADC_INIT_DAT pHalADCInitDataTmp = &HalADCInitDataTmp;
// ConfigDebugErr &= (~(_DBG_ADC_|_DBG_GDMA_));
// ConfigDebugInfo&= (~(_DBG_ADC_|_DBG_GDMA_));
adc_idx = pin & 0x0F;
/* Get I2C device handler */
pSalADCMngtAdpt = &(obj->SalADCMngtAdpt);
pSalADCUserCBAdpt = (PSAL_ADC_USERCB_ADPT)&(obj->SalADCUserCBAdpt);
/*To assign the rest pointers*/
pSalADCMngtAdpt->pSalHndPriv = &(obj->SalADCHndPriv);
pSalADCMngtAdpt->pSalHndPriv->ppSalADCHnd = (void**)&(pSalADCMngtAdpt->pSalHndPriv);
/* To assign the default (ROM) HAL OP initialization function */
pSalADCMngtAdpt->pHalOpInit = &HalADCOpInit;
/* To assign the default (ROM) HAL GDMA OP initialization function */
pSalADCMngtAdpt->pHalGdmaOpInit = &HalGdmaOpInit;
/* To assign the default (ROM) SAL interrupt function */
pSalADCMngtAdpt->pSalIrqFunc = &ADCISRHandle;
/* To assign the default (ROM) SAL DMA TX interrupt function */
pSalADCMngtAdpt->pSalDMAIrqFunc = &ADCGDMAISRHandle;
/* To backup user config first */
_memcpy(pHalADCInitDataTmp, &(obj->HalADCInitData), sizeof(HAL_ADC_INIT_DAT));
pSalADCMngtAdpt->pHalInitDat = &(obj->HalADCInitData);
pSalADCMngtAdpt->pHalOp = &(obj->HalADCOp);
pSalADCMngtAdpt->pIrqHnd = &(obj->ADCIrqHandleDat);
pSalADCMngtAdpt->pHalGdmaAdp = &(obj->HalADCGdmaAdpt);
pSalADCMngtAdpt->pHalGdmaOp = &(obj->HalADCGdmaOp);
pSalADCMngtAdpt->pIrqGdmaHnd = &(obj->ADCGdmaIrqHandleDat);
pSalADCMngtAdpt->pUserCB = &(obj->SalADCUserCB);
/* Assign the private SAL handle to public SAL handle */
pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv);
/* Assign the internal HAL initial data pointer to the SAL handle */
pSalADCHND->pInitDat = pSalADCMngtAdpt->pHalInitDat;
/* Assign the internal user callback pointer to the SAL handle */
pSalADCHND->pUserCB = pSalADCMngtAdpt->pUserCB;
/*To assign user callback pointers*/
pSalADCMngtAdpt->pUserCB->pTXCB = pSalADCUserCBAdpt;
pSalADCMngtAdpt->pUserCB->pTXCCB = (pSalADCUserCBAdpt+1);
pSalADCMngtAdpt->pUserCB->pRXCB = (pSalADCUserCBAdpt+2);
pSalADCMngtAdpt->pUserCB->pRXCCB = (pSalADCUserCBAdpt+3);
pSalADCMngtAdpt->pUserCB->pRDREQCB = (pSalADCUserCBAdpt+4);
pSalADCMngtAdpt->pUserCB->pERRCB = (pSalADCUserCBAdpt+5);
pSalADCMngtAdpt->pUserCB->pDMATXCB = (pSalADCUserCBAdpt+6);
pSalADCMngtAdpt->pUserCB->pDMATXCCB = (pSalADCUserCBAdpt+7);
pSalADCMngtAdpt->pUserCB->pDMARXCB = (pSalADCUserCBAdpt+8);
pSalADCMngtAdpt->pUserCB->pDMARXCCB = (pSalADCUserCBAdpt+9);
/* Set ADC Device Number */
pSalADCHND->DevNum = adc_idx;
/* Load ADC default value */
RtkADCLoadDefault(pSalADCHND);
/* Assign ADC Pin Mux */
pSalADCHND->PinMux = 0;
pSalADCHND->OpType = ADC_RDREG_TYPE;
/* Load user setting */
if (pHalADCInitDataTmp->ADCEndian != ADC_DATA_ENDIAN_LITTLE){
pSalADCHND->pInitDat->ADCEndian = pHalADCInitDataTmp->ADCEndian;
}
if (pHalADCInitDataTmp->ADCAudioEn != ADC_FEATURE_DISABLED){
pSalADCHND->pInitDat->ADCAudioEn = pHalADCInitDataTmp->ADCAudioEn;
}
/* Init ADC now */
pSalADCHND->pInitDat->ADCBurstSz = 8;
pSalADCHND->pInitDat->ADCOneShotTD = 8;
RtkADCInit(pSalADCHND);
}
float analogin_read(analogin_t *obj){
float value;
union {
unsigned int ui[2];
unsigned short us[4];
} adata;
PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv);
RtkADCReceiveBuf(p, &adata.ui);
return (float)(adata.us[p->DevNum]) / (float)(0xCE80);
/*
uint32_t AnaloginTmp[2] = {0,0};
uint32_t AnaloginDatMsk = 0xFFFF;
uint8_t AnaloginIdx = 0;
uint32_t AnalogDat = 0;
uint32_t AnalogDatFull = 0;
PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL;
PSAL_ADC_HND pSalADCHND = NULL;
pSalADCMngtAdpt = &(obj->SalADCMngtAdpt);
pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv);
AnaloginIdx = pSalADCHND->DevNum;
RtkADCReceiveBuf(pSalADCHND,&AnaloginTmp[0]);
AnaloginDatMsk = (u32)(AnaloginDatMsk<<((u32)(16*(AnaloginIdx&0x01))));
AnalogDat = AnaloginTmp[(AnaloginIdx/2)];
AnalogDat = (AnalogDat & AnaloginDatMsk);
AnalogDat = (AnalogDat>>((u32)(16*(AnaloginIdx&0x01))));
AnalogDatFull = 0xCE80;
value = (float)(AnalogDat) / (float)(AnalogDatFull);
return (float)value;
*/
}
uint16_t analogin_read_u16(analogin_t *obj){
union {
unsigned int ui[2];
unsigned short us[4];
} adata;
PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv);
RtkADCRxManualRotate(p, &adata.ui);
return adata.us[p->DevNum];
/*
uint32_t AnaloginTmp[2] = {0,0};
uint32_t AnaloginDatMsk = 0xFFFF;
uint8_t AnaloginIdx = 0;
uint32_t AnalogDat = 0;
PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL;
PSAL_ADC_HND pSalADCHND = NULL;
pSalADCMngtAdpt = &(obj->SalADCMngtAdpt);
pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv);
AnaloginIdx = pSalADCHND->DevNum;
RtkADCRxManualRotate(pSalADCHND,&AnaloginTmp[0]);
//DBG_8195A("[0]:%08x, %08x\n", AnaloginTmp[0], AnaloginTmp[1] );
AnaloginDatMsk = (u32)(AnaloginDatMsk<<((u32)(16*(AnaloginIdx&0x01))));
AnalogDat = AnaloginTmp[(AnaloginIdx/2)];
AnalogDat = (AnalogDat & AnaloginDatMsk);
AnalogDat = (AnalogDat>>((u32)(16*(AnaloginIdx&0x01))));
return (uint16_t)AnalogDat;
*/
}
void analogin_deinit(analogin_t *obj){
/*
PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL;
PSAL_ADC_HND pSalADCHND = NULL;
pSalADCMngtAdpt = &(obj->SalADCMngtAdpt);
p = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); */
PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv);
/* To deinit analogin */
RtkADCDeInit(p);
}
#endif

View file

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_PORTIN 1
#define DEVICE_PORTOUT 1
#define DEVICE_PORTINOUT 1
#define DEVICE_INTERRUPTIN 1
#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 1
#define DEVICE_SERIAL 1
#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1
#define DEVICE_SPISLAVE 1
#define DEVICE_CAN 0
#define DEVICE_RTC 1
#define DEVICE_ETHERNET 1
#define DEVICE_PWMOUT 1
#define DEVICE_SLEEP 1
#include "objects.h"
#endif

View file

@ -0,0 +1,89 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "dma_api.h"
#include "cmsis.h"
extern BOOL HalGdmaMemCpyInit(PHAL_GDMA_OBJ pHalGdmaObj);
extern VOID HalGdmaMemCpyDeInit(PHAL_GDMA_OBJ pHalGdmaObj);
extern VOID* HalGdmaMemCpy(PHAL_GDMA_OBJ pHalGdmaObj, void* pDest, void* pSrc, u32 len);
extern VOID HalGdmaMemAggr(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock);
extern BOOL HalGdmaMemCpyAggrInit(PHAL_GDMA_OBJ pHalGdmaObj);
/**
* @brief Initial the GDMA
*
* @param dma_obj: the GDMA object
* handler: the callback function for a DMA transfer complete.
* id: the argument of the callback function.
* @return None
*
*/
void dma_memcpy_aggr_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id)
{
dma_obj->gdma_obj.GdmaIrqHandle.IrqFun = (IRQ_FUN)handler;
dma_obj->gdma_obj.GdmaIrqHandle.Data = (u32)id;
dma_obj->gdma_allocated = HalGdmaMemCpyAggrInit(&(dma_obj->gdma_obj));
}
void dma_memcpy_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id)
{
dma_obj->gdma_obj.GdmaIrqHandle.IrqFun = (IRQ_FUN)handler;
dma_obj->gdma_obj.GdmaIrqHandle.Data = (u32)id;
dma_obj->gdma_allocated = HalGdmaMemCpyInit(&(dma_obj->gdma_obj));
}
/**
* @brief De-Initial the GDMA
*
* @param dma_obj: the GDMA object
* @return None
*
*/
void dma_memcpy_deinit(gdma_t *dma_obj)
{
if (dma_obj->gdma_allocated) {
HalGdmaMemCpyDeInit(&(dma_obj->gdma_obj));
}
}
/**
* @brief To do a memory copy by DMA
*
* @param None
* @return None
*
*/
void dma_memcpy(gdma_t *dma_obj, void *dst, void* src, uint32_t len)
{
#if 0
if (!dma_obj->gdma_allocated) {
dma_irq_handler handler;
_memcpy(dst, src, len);
handler = dma_obj->GdmaIrqHandle.IrqFun;
handler(dma_obj->GdmaIrqHandle.Data);
}
#endif
HalGdmaMemCpy(&(dma_obj->gdma_obj), dst, src, len);
}
void dma_memcpy_aggr(gdma_t *dma_obj, PHAL_GDMA_BLOCK block_info)
{
HalGdmaMemAggr(&(dma_obj->gdma_obj), block_info);
}

View file

@ -0,0 +1,155 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "rtl8195a.h"
#ifdef CONFIG_EFUSE_EN
/* in hal_efuse.h
extern VOID ReadEfuseContant1(OUT u8 *pContant);
extern u8 WriteEfuseContant1(IN u8 CodeWordNum, IN u8 WordEnable, IN u8 *pContant);
extern VOID ReadEOTPContant(OUT u8 *pContant);
extern VOID WriteEOTPContant(IN u8 *pContant);
extern u8 GetRemainingEfuseLength(void);
extern VOID HALJtagOff(VOID);
*/
/**
* @brief get remaining efuse length
* @retval remaining efuse length
*/
int efuse_get_remaining_length(void)
{
return GetRemainingEfuseLength();
}
/**
* @brief Read efuse contant of specified user
* @param data: Specified the address to save the readback data.
*/
void efuse_mtp_read(uint8_t * data)
{
ReadEfuseContant1(data);
return;
}
/**
* @brief Write user's contant to efuse
* @param *data: Specified the data to be programmed.
* @param len: Specifies the data length of programmed data.
* @retval status: Success:0~32 or Failure: -1.
*/
int efuse_mtp_write(uint8_t *data, uint8_t len)
{
u8 len_low, len_high, word_enable = 0;
if( (len & 0x01) == 1)
len += 1;
if(len > 32){
return -1;
}
if(len == 0){
return 0;
}
len_low = len & 0x07;
len_high = (len >> 3) & 0x07;
if(len_low == 0)
word_enable = 0;
else if(len_low == 2)
word_enable = 1;
else if(len_low == 4)
word_enable = 3;
else if(len_low == 6)
word_enable = 7;
switch (len_high){
case 0:
WriteEfuseContant1(0, word_enable, data);
break;
case 1:
WriteEfuseContant1(0, 0xf, data);
WriteEfuseContant1(1, word_enable, data+8);
break;
case 2:
WriteEfuseContant1(0, 0xf, data);
WriteEfuseContant1(1, 0xf, data+8);
WriteEfuseContant1(2, word_enable, data+8);
break;
case 3:
WriteEfuseContant1(0, 0xf, data);
WriteEfuseContant1(1, 0xf, data+8);
WriteEfuseContant1(2, 0xf, data+16);
WriteEfuseContant1(3, word_enable, data+24);
break;
case 4:
WriteEfuseContant1(0, 0xf, data);
WriteEfuseContant1(1, 0xf, data+8);
WriteEfuseContant1(2, 0xf, data+16);
WriteEfuseContant1(3, 0xf, data+24);
}
return len;
}
/**
* @brief Read efuse OTP contant
* @param address: Specifies the offset of the OTP.
* @param len: Specifies the length of readback data.
* @param buf: Specified the address to save the readback data.
*/
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;
}
/**
* @brief Write user's contant to OTP efuse
* @param address: Specifies the offset of the programmed OTP.
* @param len: Specifies the data length of programmed data.
* @param *buf: Specified the data to be programmed.
* @retval status: Success:0 or Failure: -1.
*/
int efuse_otp_write(u8 address, u8 len, u8 *buf)
{
u8 content[32]; // the OTP max length is 32
if((address+len) > 32)
return -1;
_memset(content, 0xFF, 32);
_memcpy(content+address, buf, len);
WriteEOTPContant(content);
return 0;
}
/**
* @brief Disable jtag
*/
int efuse_disable_jtag(void)
{
HALJtagOff();
return 0;
}
#endif

View file

@ -0,0 +1,104 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "ethernet_api.h"
#include "ethernet_ex_api.h"
#include "hal_mii.h"
#if DEVICE_ETHERNET
#if CONFIG_MII_EN
extern HAL_ETHER_ADAPTER HalEtherAdp;
void ethernet_irq_hook(ethernet_callback callback)
{
HalEtherAdp.CallBack = callback;
}
void ethernet_set_descnum(uint8_t txdescCnt, uint8_t rxdescCnt)
{
HalEtherAdp.tx_desc_num = txdescCnt;
HalEtherAdp.rx_desc_num = rxdescCnt;
}
void ethernet_trx_pre_setting(uint8_t *TxDescAddr, uint8_t *RxDescAddr, uint8_t *pTxPktBuf, uint8_t *pRxPktBuf)
{
HalEtherAdp.TxDescAddr = TxDescAddr;
HalEtherAdp.RxDescAddr = RxDescAddr;
HalEtherAdp.pTxPktBuf = pTxPktBuf;
HalEtherAdp.pRxPktBuf = pRxPktBuf;
}
int ethernet_init(void)
{
return HalMiiInit();
}
void ethernet_free(void)
{
HalMiiDeInit();
}
int ethernet_write(const char *data, int size)
{
return HalMiiWriteData(data, size);
}
int ethernet_send(void)
{
return HalMiiSendPacket();
}
int ethernet_receive(void)
{
return HalMiiReceivePacket();
}
int ethernet_read(char *data, int size)
{
return HalMiiReadData((u8*)data, size);
}
void ethernet_address(char *mac)
{
HalMiiGetMacAddress((u8*)mac);
}
int ethernet_link(void)
{
int ret;
ret = HalMiiGetLinkStatus();
return ret;
}
void ethernet_set_link(int speed, int duplex)
{
HalMiiForceLink(speed, duplex);
}
#endif // #if CONFIG_MII_EN
#endif // #if DEVICE_ETHERNET

View file

@ -0,0 +1,635 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "PinNames.h"
#include "pinmap.h"
#include "rtl8195a.h"
#include "hal_spi_flash.h"
#include "hal_platform.h"
#include "rtl8195a_spi_flash.h"
#include "hal_api.h"
#include "flash_api.h"
extern u32 ConfigDebugInfo;
extern SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // SpicMaxMode = 3, CPU_CLK_TYPE_NO = 6 !
_LONG_CALL_
extern VOID SpicWaitBusyDoneRtl8195A(VOID);
bool fspic_isinit = 0;
flash_t flashobj;
/**
* global data structure
*/
//flash_t flash;
/**
* @brief Control the flash chip write protect enable/disable
* @param protect: 1/0: protect/unprotect
* @retval none
*/
void flash_write_protect(flash_t *obj, uint32_t protect) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicWriteProtectFlashRtl8195A(protect);
SpicDisableRtl8195A();
}
/**
* @brief Init Flash
* @param obj: address of the flash object
* @retval none
*/
void flash_init(flash_t *obj) {
//SPIC_INIT_PARA spic_init_para;
// Init SPI Flash Controller
#if CONFIG_DEBUG_LOG > 4
DBG_8195A("Initial Spi Flash Controller\n");
#endif
u8 flmode;
SPI_FLASH_PIN_FCTRL(ON);
#if 0
if (SpicFlashInitRtl8195A(SpicQuadBitMode)) {
flmode = SpicQuadBitMode;
fspic_isinit = 1;
}
else
#endif
if (SpicFlashInitRtl8195A(SpicDualBitMode)) { // SpicFlashInitRtl8195A(SpicQuadBitMode)
flmode = SpicDualBitMode;
fspic_isinit = 1;
} else if (SpicFlashInitRtl8195A(SpicOneBitMode)) {
flmode = SpicOneBitMode;
fspic_isinit = 1;
} else {
DBG_8195A("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);
// flmode = SpicOneBitMode;
return;
}
u8 curclk = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1)
>> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL;
flashobj.SpicInitPara = SpicInitParaAllClk[flmode][curclk];
flashobj.SpicInitPara.Mode.CpuClk = curclk;
flashobj.SpicInitPara.Mode.BitMode = flmode;
#if CONFIG_DEBUG_LOG > 3
DBG_SPIF_INFO("Flash ID: %02x%02x%02x\n", flashobj.SpicInitPara.id[0], flashobj.SpicInitPara.id[1], flashobj.SpicInitPara.id[2]);
DBG_SPIF_INFO("Flash Mode: 0x%02x; BaudRate:%d; RdDummyCyle:%d; DelayLine:%d\n",
flashobj.SpicInitPara.Mode.BitMode, flashobj.SpicInitPara.BaudRate, flashobj.SpicInitPara.RdDummyCyle, flashobj.SpicInitPara.DelayLine);
DBG_SPIF_INFO("Flash Size: %d bytes\n", flash_get_size(obj));
#endif
}
void flash_turnon(void) {
SPI_FLASH_PIN_FCTRL(ON);
SpicWaitBusyDoneRtl8195A();
}
/**
* @brief Erase flash sector
* @param address: Specifies the starting address to be erased.
* @retval none
*/
void flash_erase_sector(flash_t *obj, uint32_t address) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address);
SpicDisableRtl8195A();
}
void flash_erase_block(flash_t *obj, uint32_t address) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address);
SpicDisableRtl8195A();
}
/**
* @brief Read a word from specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be read.
* @param data: Specified the address to save the readback data.
* @retval status: Success:1 or Failure: Others.
*/
int flash_read_word(flash_t *obj, uint32_t address, uint32_t * data) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
*data = HAL_READ32(SPI_FLASH_BASE, address);
SpicDisableRtl8195A();
return 1;
}
/**
* @brief Write a word to specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be programmed.
* @param data: Specified the data to be programmed.
* @retval status: Success:1 or Failure: Others.
*/
int flash_write_word(flash_t *obj, uint32_t address, uint32_t data) {
u8 flashtype = 0;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
flashtype = flashobj.SpicInitPara.flashtype;
//Write word
HAL_WRITE32(SPI_FLASH_BASE, address, data);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
SpicDisableRtl8195A();
return 1;
}
/**
* @brief Read a stream of data from specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be read.
* @param len: Specifies the length of the data to read.
* @param data: Specified the address to save the readback data.
* @retval status: Success:1 or Failure: Others.
*/
int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len,
uint8_t * data) {
u32 offset_to_align;
u32 i;
u32 read_word;
uint8_t *ptr;
uint8_t *pbuf;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
offset_to_align = address & 0x03;
pbuf = data;
if (offset_to_align != 0) {
// the start address is not 4-bytes aligned
read_word = HAL_READ32(SPI_FLASH_BASE, (address - offset_to_align));
ptr = (uint8_t*) &read_word + offset_to_align;
offset_to_align = 4 - offset_to_align;
for (i = 0; i < offset_to_align; i++) {
*pbuf = *(ptr + i);
pbuf++;
len--;
if (len == 0) {
break;
}
}
}
address = (((address - 1) >> 2) + 1) << 2; // address = next 4-bytes aligned
ptr = (uint8_t*) &read_word;
if ((u32) pbuf & 0x03) {
while (len >= 4) {
read_word = HAL_READ32(SPI_FLASH_BASE, address);
for (i = 0; i < 4; i++) {
*pbuf = *(ptr + i);
pbuf++;
}
address += 4;
len -= 4;
}
} else {
while (len >= 4) {
*((u32 *) pbuf) = HAL_READ32(SPI_FLASH_BASE, address);
pbuf += 4;
address += 4;
len -= 4;
}
}
if (len > 0) {
read_word = HAL_READ32(SPI_FLASH_BASE, address);
for (i = 0; i < len; i++) {
*pbuf = *(ptr + i);
pbuf++;
}
}
SpicDisableRtl8195A();
return 1;
}
/**
* @brief Write a stream of data to specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be read.
* @param len: Specifies the length of the data to write.
* @param data: Specified the pointer of the data to be written.
* @retval status: Success:1 or Failure: Others.
*/
int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len,
uint8_t * data) {
u32 offset_to_align;
u32 align_addr;
u32 i;
u32 write_word;
uint8_t *ptr;
uint8_t *pbuf;
u8 flashtype = 0;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
flashtype = flashobj.SpicInitPara.flashtype;
offset_to_align = address & 0x03;
pbuf = data;
if (offset_to_align != 0) {
// the start address is not 4-bytes aligned
align_addr = (address - offset_to_align);
write_word = HAL_READ32(SPI_FLASH_BASE, align_addr);
ptr = (uint8_t*) &write_word + offset_to_align;
offset_to_align = 4 - offset_to_align;
for (i = 0; i < offset_to_align; i++) {
*(ptr + i) = *pbuf;
pbuf++;
len--;
if (len == 0) {
break;
}
}
//Write word
HAL_WRITE32(SPI_FLASH_BASE, align_addr, write_word);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
}
address = (((address - 1) >> 2) + 1) << 2; // address = next 4-bytes aligned
if ((u32) pbuf & 0x03) {
while (len >= 4) {
write_word = (u32) (*pbuf) | ((u32) (*(pbuf + 1)) << 8)
| ((u32) (*(pbuf + 2)) << 16) | ((u32) (*(pbuf + 3)) << 24);
//Write word
HAL_WRITE32(SPI_FLASH_BASE, address, write_word);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
pbuf += 4;
address += 4;
len -= 4;
}
} else {
while (len >= 4) {
//Write word
HAL_WRITE32(SPI_FLASH_BASE, address, (u32)*((u32 *)pbuf));
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
pbuf += 4;
address += 4;
len -= 4;
}
}
if (len > 0) {
write_word = HAL_READ32(SPI_FLASH_BASE, address);
ptr = (uint8_t*) &write_word;
for (i = 0; i < len; i++) {
*(ptr + i) = *pbuf;
pbuf++;
}
//Write word
HAL_WRITE32(SPI_FLASH_BASE, address, write_word);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
}
SpicDisableRtl8195A();
return 1;
}
/*
Function Description:
This function performans the same functionality as the function flash_stream_write.
It enhances write performance by reducing overheads.
Users can use either of functions depending on their needs.
* @brief Write a stream of data to specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be read.
* @param Length: Specifies the length of the data to write.
* @param data: Specified the pointer of the data to be written.
* @retval status: Success:1 or Failure: Others.
*/
int flash_burst_write(flash_t *obj, uint32_t address, uint32_t Length,
uint8_t * data) {
u32 OccuSize;
u32 ProgramSize;
u32 PageSize;
u8 flashtype = 0;
PageSize = 256;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
flashtype = flashobj.SpicInitPara.flashtype;
OccuSize = address & 0xFF;
if ((Length >= PageSize) || ((Length + OccuSize) >= PageSize))
ProgramSize = PageSize - OccuSize;
else
ProgramSize = Length;
flashobj.Length = Length;
while (Length > 0) {
if (OccuSize) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address,
&(flashobj.Length));
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
address += ProgramSize;
data += ProgramSize;
Length -= ProgramSize;
OccuSize = 0;
} else {
while ((flashobj.Length) >= PageSize) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address,
&(flashobj.Length));
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
address += PageSize;
data += PageSize;
Length -= PageSize;
}
flashobj.Length = Length;
if ((flashobj.Length) > 0) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address,
&(flashobj.Length));
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
break;
}
}
flashobj.Length = Length;
}
SpicDisableRtl8195A();
return 1;
}
/**
* @brief Read a stream of data from specified address
* @param obj: Specifies the parameter of flash object.
* @param address: Specifies the address to be read.
* @param len: Specifies the length of the data to read.
* @param data: Specified the address to save the readback data.
* @retval status: Success:1 or Failure: Others.
*/
int flash_burst_read(flash_t *obj, uint32_t address, uint32_t Length,
uint8_t * data) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicDisableRtl8195A();
return 1;
}
int flash_get_status(flash_t *obj) {
u8 Status = 0;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
Status = SpicGetFlashStatusRefinedRtl8195A(flashobj.SpicInitPara);
SpicDisableRtl8195A();
return Status;
}
/*
Function Description:
Please refer to the datatsheet of flash for more details of the content of status register.
The block protected area and the corresponding control bits are provided in the flash datasheet.
* @brief Set Status register to enable desired operation
* @param obj: Specifies the parameter of flash object.
* @param data: Specifies which bit users like to set
ex: if users want to set the third bit, data = 0x8.
*/
int flash_set_status(flash_t *obj, uint32_t data) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
DBG_8195A("Status Register After Setting= %x\n",
flash_get_status(&flashobj));
SpicDisableRtl8195A();
return 1;
}
/*
Function Description:
This function aims to reset the status register, please make sure the operation is appropriate.
*/
void flash_reset_status(flash_t *obj) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicSetFlashStatusRefinedRtl8195A(0, flashobj.SpicInitPara);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
SpicDisableRtl8195A();
}
/*
Function Description:
This function is only for Micron 512Mbit flash to access beyond 128Mbit by switching between four 128 Mbit area.
Please refer to flash datasheet for more information about memory mapping.
*/
int flash_set_extend_addr(flash_t *obj, uint32_t data) {
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicSetExtendAddrRtl8195A(data, flashobj.SpicInitPara);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
DBG_8195A("Extended Address Register After Setting = %x\n",
flash_get_extend_addr(&flashobj));
SpicDisableRtl8195A();
return 1;
}
int flash_get_extend_addr(flash_t *obj) {
u8 Status = 0;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
Status = SpicGetExtendAddrRtl8195A(flashobj.SpicInitPara);
SpicDisableRtl8195A();
return Status;
}
/*
* Return Flash size in bytes
* = 0 - unknown flash
*/
unsigned int flash_get_size(flash_t *obj) {
unsigned int flashchip_size = 0;
if (fspic_isinit == 0) {
flash_turnon();
flash_init(&flashobj);
SpicDisableRtl8195A();
if (fspic_isinit == 0)
return flashchip_size;
}
if (flashobj.SpicInitPara.id[2] > 0x11
&& flashobj.SpicInitPara.id[2] < 0x20) {
flashchip_size = 1 << (flashobj.SpicInitPara.id[2]); // Flash size in bytes
} else
flashchip_size = 1024 * 1024; // default 1 mbytes?
return flashchip_size;
}
/*
* Read Flash OTP data
*/
int flash_otp_read(flash_t *obj, uint32_t address, uint32_t Length,
uint8_t * data) {
int ret = 1;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
switch (flashobj.SpicInitPara.flashtype) {
case FLASH_MXIC_4IO:
case FLASH_MXIC: // Only 512 bits
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("MXIC: Only 512 bits!\n");
#endif
SpicTxCmdWithDataRtl8195A(FLASH_CMD_ENSO, 0, 0, flashobj.SpicInitPara); // enter secured OTP
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicTxCmdWithDataRtl8195A(FLASH_CMD_EXSO, 0, 0, flashobj.SpicInitPara); // exit secured OTP
break;
case FLASH_EON: // OTP sector is mapping to sector 1023
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("EON: OTP sector is mapping to sector 1023!\n");
#endif
SpicTxCmdWithDataRtl8195A(FLASH_CMD_EOTPM, 0, 0, flashobj.SpicInitPara); // enter secured OTP
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicTxCmdWithDataRtl8195A(FLASH_CMD_WRDI, 0, 0, flashobj.SpicInitPara); // exit secured OTP
break;
case FLASH_MICRON: // (4Bh) READ OTP ARRAY
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("MICRON: @TODO !\n");
#endif
// FLASH_CMD_ROTPA
ret = 0;
break;
default:
DBG_8195A("Flash type?");
ret = 0;
}
SpicDisableRtl8195A();
return ret;
}

View file

@ -0,0 +1,521 @@
/*
* flash_eep.c
*
* Created on: 19/01/2015
* Port RTL87xx: 15/10/16
* Author: pvvx
*/
#include <rtl8195a.h>
//#include <FreeRTOS.h>
//#include <queue.h>
#include <osdep_api.h>
#include <osdep_service.h>
#include "device_lock.h"
#include "flash_api.h"
#include "flash_eep.h"
//-----------------------------------------------------------------------------
#ifdef CONFIG_DEBUG_LOG
#define DEBUGSOO CONFIG_DEBUG_LOG
#else
#define DEBUGSOO 0
#endif
#define mMIN(a, b) ((a < b)? a : b)
#define align(a) ((a + 3) & 0xFFFFFFFC)
typedef union // заголовок объекта сохранения feep
{
struct {
unsigned short size;
unsigned short id;
} __attribute__((packed)) n;
unsigned int x;
} __attribute__((packed)) fobj_head;
#define fobj_head_size 4
#define fobj_x_free 0xffffffff
#define MAX_FOBJ_SIZE 512 // максимальный размер сохраняемых объeктов
#define FMEM_ERROR_MAX 5
//-----------------------------------------------------------------------------
flash_t flash;
//QueueHandle_t flash_mutex;
//-----------------------------------------------------------------------------
/*-------------------------------------------------------------------------------------
Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram)
--------------------------------------------------------------------------------------*/
void FLASH_EEP_ATTR copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len)
{
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
unsigned int xlen = (unsigned int)ps & 3;
// unsigned int size = len;
if(xlen) {
tmp.ud = *p++;
while (len) {
len--;
*pd++ = tmp.uc[xlen++];
if(xlen & 4) break;
}
}
xlen = len >> 2;
while(xlen) {
tmp.ud = *p++;
*pd++ = tmp.uc[0];
*pd++ = tmp.uc[1];
*pd++ = tmp.uc[2];
*pd++ = tmp.uc[3];
xlen--;
}
if(len & 3) {
tmp.ud = *p;
pd[0] = tmp.uc[0];
if(len & 2) {
pd[1] = tmp.uc[1];
if(len & 1) {
pd[2] = tmp.uc[2];
}
}
}
// return size;
}
/*------------------------------------------------------------------------------------
Копирует данные из области align(1) (ram) в область align(4) (flash, registers)
--------------------------------------------------------------------------------------*/
void FLASH_EEP_ATTR copy_align1_to_align4(void * pd, unsigned char * ps, unsigned int len)
{
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
unsigned int *p = (unsigned int *)(((unsigned int)pd) & (~3));
unsigned int xlen = (unsigned int)pd & 3;
// unsigned int size = len;
if(xlen) {
tmp.ud = *p;
while (len) {
len--;
tmp.uc[xlen++] = *ps++;
if(xlen & 4) break;
}
*p++ = tmp.ud;
}
xlen = len >> 2;
while(xlen) {
tmp.uc[0] = *ps++;
tmp.uc[1] = *ps++;
tmp.uc[2] = *ps++;
tmp.uc[3] = *ps++;
*p++ = tmp.ud;
xlen--;
}
if(len & 3) {
tmp.ud = *p;
tmp.uc[0] = ps[0];
if(len & 2) {
tmp.uc[1] = ps[1];
if(len & 1) {
tmp.uc[2] = ps[2];
}
}
*p = tmp.ud;
}
// return size;
}
/*------------------------------------------------------------------------------------
Запись байта в область align(4) (flash, registers)
--------------------------------------------------------------------------------------*/
void FLASH_EEP_ATTR write_align4_chr(unsigned char *pd, unsigned char c)
{
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
unsigned int *p = (unsigned int *)((unsigned int)pd & (~3));
unsigned int xlen = (unsigned int)pd & 3;
tmp.ud = *p;
tmp.uc[xlen] = c;
*p = tmp.ud;
}
/*------------------------------------------------------------------------------------
Чтение байта из области align(4) (flash, registers)
--------------------------------------------------------------------------------------*/
unsigned char FLASH_EEP_ATTR get_align4_chr(const unsigned char *ps)
{
return (*((unsigned int *)((unsigned int)ps & (~3))))>>(((unsigned int)ps & 3) << 3);
}
/*------------------------------------------------------------------------------------
Сравнение данных в области align(4) (flash, registers, ...) с областью align(1) (ram)
--------------------------------------------------------------------------------------*/
int FLASH_EEP_ATTR cmp_align1_align4(unsigned char * pd, void * ps, unsigned int len)
{
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
unsigned int *p = (unsigned int *)((unsigned int)ps & (~3));
unsigned int xlen = (unsigned int)ps & 3;
if(xlen) {
tmp.ud = *p++;
while (len) {
len--;
if(*pd++ != tmp.uc[xlen++]) return 1;
if(xlen & 4) break;
}
}
xlen = len >> 2;
while(xlen) {
tmp.uc[0] = *pd++;
tmp.uc[1] = *pd++;
tmp.uc[2] = *pd++;
tmp.uc[3] = *pd++;
if(*p++ != tmp.ud) return 1;
xlen--;
}
if(len & 3) {
tmp.ud = *p;
if(pd[0] != tmp.uc[0]) return 1;
if(len & 2) {
if(pd[1] != tmp.uc[1]) return 1;
if(len & 1) {
if(pd[2] != tmp.uc[2]) return 1;
}
}
}
return 0;
}
//-----------------------------------------------------------------------------
LOCAL void _fwrite_word(unsigned int addr, unsigned int dw)
{
//Write word
HAL_WRITE32(SPI_FLASH_BASE, addr, dw);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
if(flashobj.SpicInitPara.flashtype == FLASH_MICRON)
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_bscfg
// Опции:
// false - поиск текушего сегмента
// true - поиск нового сегмента для записи (pack)
// Returns : новый адрес сегмента для записи
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
LOCAL FLASH_EEP_ATTR unsigned int get_addr_bscfg(bool flg)
{
unsigned int x1 = (flg)? 0 : 0xFFFFFFFF, x2;
unsigned int faddr = FMEMORY_SCFG_BASE_ADDR;
unsigned int reta = FMEMORY_SCFG_BASE_ADDR;
do {
x2 = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &x2, 4)) return -(FMEM_FLASH_ERR);
if(flg) { // поиск нового сегмента для записи (pack)
if(x2 > x1 || x2 == 0xFFFFFFFF) {
x1 = x2;
reta = faddr; // новый адрес сегмента для записи
}
}
else if(x2 < x1) { // поиск текушего сегмента
x1 = x2;
reta = faddr; // новый адрес сегмента для записи
};
faddr += FMEMORY_SCFG_BANK_SIZE;
} while(faddr < (FMEMORY_SCFG_BASE_ADDR + FMEMORY_SCFG_BANKS * FMEMORY_SCFG_BANK_SIZE));
if((!flg)&&(x1 == 0xFFFFFFFF)&&(reta == FMEMORY_SCFG_BASE_ADDR)) {
_fwrite_word(reta, --x1); // if(flash_write(reta, &x1, 4)) return -(FMEM_FLASH_ERR);
}
#if DEBUGSOO > 3
DBG_FEEP_INFO("base seg: %p [%d]\n", reta, x2);
#endif
return reta;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fobj
// Опции:
// false - Поиск последней записи объекта по id и size
// true - Поиск присуствия записи объекта по id и size
// Returns : адрес записи данных объекта
// 0 - не найден
// ret < FMEM_ERROR_MAX - ошибка
//-----------------------------------------------------------------------------
LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj(unsigned int base, fobj_head *obj, bool flg)
{
// if(base == 0) return 0;
fobj_head fobj;
unsigned int faddr = base + 4;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size);
unsigned int reta = 0;
do {
fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if(fobj.x == fobj_x_free) break;
if(fobj.n.size <= MAX_FOBJ_SIZE) {
if(fobj.n.id == obj->n.id) {
if(flg) {
return faddr;
}
obj->n.size = fobj.n.size;
reta = faddr;
}
faddr += align(fobj.n.size + fobj_head_size);
}
else faddr += align(MAX_FOBJ_SIZE + fobj_head_size);
}
while(faddr < fend);
return reta;
}
//-----------------------------------------------------------------------------
// FunctionName : get_addr_fend
// Поиск последнего адреса в сегменте для записи объекта
// Returns : адрес для записи объекта
// ret < FMEM_ERROR_MAX - ошибка
// ret = 0 - не влезет, на pack
//-----------------------------------------------------------------------------
LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj_save(unsigned int base, fobj_head obj)
{
fobj_head fobj;
unsigned int faddr = base + 4;
unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(obj.n.size + fobj_head_size);
do {
fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR);
if(fobj.x == fobj_x_free) {
if(faddr < fend) {
return faddr;
}
return 0; // не влезет, на pack
}
if(fobj.n.size <= MAX_FOBJ_SIZE) {
faddr += align(fobj.n.size + fobj_head_size);
}
else faddr += align(MAX_FOBJ_SIZE + fobj_head_size);
}
while(faddr < fend);
return 0; // не влезет, на pack
}
//=============================================================================
// FunctionName : pack_cfg_fmem
// Returns : адрес для записи объекта
//-----------------------------------------------------------------------------
LOCAL FLASH_EEP_ATTR unsigned int pack_cfg_fmem(fobj_head obj)
{
fobj_head fobj;
unsigned int fnewseg = get_addr_bscfg(true); // поиск нового сегмента для записи (pack)
if(fnewseg < FMEM_ERROR_MAX) return fnewseg; // error
unsigned int foldseg = get_addr_bscfg(false); // поиск текушего сегмента
if(foldseg < FMEM_ERROR_MAX) return fnewseg; // error
unsigned int faddr = foldseg;
unsigned int rdaddr, wraddr;
unsigned short len;
unsigned int * pbuf = (unsigned int *) malloc(align(MAX_FOBJ_SIZE + fobj_head_size) >> 2);
if(pbuf == NULL) {
#if DEBUGSOO > 1
DBG_FEEP_ERR("pack malloc error!\n");
#endif
return -(FMEM_MEM_ERR);
}
#if DEBUGSOO > 3
DBG_FEEP_INFO("repack base to new seg: %p\n", fnewseg);
#endif
SpicSectorEraseFlashRtl8195A(fnewseg); // if(flash_erase_sector(fnewseg)) return -(FMEM_FLASH_ERR);
faddr += 4;
wraddr = fnewseg + 4;
do {
fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); //if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); // последовательное чтение id из старого сегмента
if(fobj.x == fobj_x_free) break;
if(fobj.n.size > MAX_FOBJ_SIZE) len = align(MAX_FOBJ_SIZE + fobj_head_size);
else len = align(fobj.n.size + fobj_head_size);
if(fobj.n.id != obj.n.id && fobj.n.size <= MAX_FOBJ_SIZE) { // объект валидный
if(get_addr_fobj(fnewseg, &fobj, true) == 0) { // найдем, сохранили ли мы его уже? нет
rdaddr = get_addr_fobj(foldseg, &fobj, false); // найдем последнее сохранение объекта в старом сенгменте, size изменен
if(rdaddr < FMEM_ERROR_MAX) return rdaddr; // ???
if(wraddr + len >= fnewseg + FMEMORY_SCFG_BANK_SIZE) {
#if DEBUGSOO > 1
DBG_FEEP_ERR("pack segment overflow!\n");
#endif
return -(FMEM_OVR_ERR);
};
#if 0
copy_align4_to_align1((uint8 *)pbuf, rdaddr, len);
#else
SpicUserReadFourByteRtl8195A(len, rdaddr, (unsigned int *)pbuf, flashobj.SpicInitPara.Mode.BitMode);
#endif
int i = 0;
int size4b = len >> 2;
// перепишем данные obj в новый сектор
while(size4b--) {
_fwrite_word(wraddr, pbuf[i++]); // if(flash_write(wraddr, &pbuf[i++], 4)) return -(FMEM_FLASH_ERR);
};
};
};
faddr += len;
} while(faddr < (foldseg + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size+1)));
free(pbuf);
// обратный счетчик стираний/записей секторов как id
_fwrite_word(fnewseg, HAL_READ32(SPI_FLASH_BASE, foldseg) - 1); // if(flash_write(fnewseg, &foldseg + SPI_FLASH_BASE, 4)) return -(FMEM_FLASH_ERR);
#if DEBUGSOO > 3
DBG_FEEP_INFO("free: %d\n", FMEMORY_SCFG_BANK_SIZE - (faddr & (FMEMORY_SCFG_BANK_SIZE-1)));
#endif
return get_addr_fobj_save(fnewseg, obj); // адрес для записи объекта;
}
//-----------------------------------------------------------------------------
LOCAL signed short FLASH_EEP_ATTR _flash_write_cfg(void *ptr, unsigned short id, unsigned short size)
{
fobj_head fobj;
fobj.n.id = id;
fobj.n.size = size;
bool retb = false;
unsigned int faddr = get_addr_bscfg(false);
if(faddr >= FMEM_ERROR_MAX) {
unsigned int xfaddr = get_addr_fobj(faddr, &fobj, false);
if(xfaddr > FMEM_ERROR_MAX && size == fobj.n.size) {
if(size == 0
|| cmp_align1_align4(ptr, (void *)SPI_FLASH_BASE + xfaddr + fobj_head_size, size) == 0) {
#if DEBUGSOO > 3
DBG_FEEP_INFO("write obj is identical, id: %04x [%d]\n", id, size);
#endif
return size; // уже записано то-же самое
}
#if DEBUGSOO > 100
else {
int i;
uint8 * p = (uint8 *)(SPI_FLASH_BASE + xfaddr + fobj_head_size);
uint8 * r = (uint8 *) ptr;
for(i=0; i < size; i+=8) {
DBG_8195A("buf[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i, r[i], r[i+1], r[i+2], r[i+3], r[i+4], r[i+5], r[i+6], r[i+7]);
DBG_8195A("obj[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
i, p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7]);
}
}
#endif
}
}
#if DEBUGSOO > 2
DBG_FEEP_INFO("write obj id: %04x [%d]\n", id, size);
#endif
fobj.n.size = size;
faddr = get_addr_fobj_save(faddr, fobj);
if(faddr == 0) {
faddr = pack_cfg_fmem(fobj);
if(faddr == 0) return FMEM_NOT_FOUND;
}
else if(faddr < FMEM_ERROR_MAX) return - faddr - 1; // error
#if DEBUGSOO > 3
DBG_FEEP_INFO("write obj to faddr %p\n", faddr);
#endif
_fwrite_word(faddr, fobj.x); // if(flash_write(faddr, &fobj.x, 4)) return FMEM_FLASH_ERR;
faddr+=4;
union {
unsigned char uc[4];
unsigned int ud;
}tmp;
#if 0
u32 len = (size + 3) & (~3);
if(len) SpicUserProgramRtl8195A((u8 *)ptr, 1, faddr, len);
#else
u32 len = (size + 3) >> 2;
uint8 * ps = ptr;
while(len--) {
tmp.uc[0] = *ps++;
tmp.uc[1] = *ps++;
tmp.uc[2] = *ps++;
tmp.uc[3] = *ps++;
_fwrite_word(faddr, tmp.ud); // if(flash_write(faddr, &tmp.ud, 4)) return FMEM_FLASH_ERR;
faddr += 4;
}
#endif
return size;
}
//=============================================================================
//- Сохранить объект в flash --------------------------------------------------
// Returns : false/true
//-----------------------------------------------------------------------------
bool FLASH_EEP_ATTR flash_write_cfg(void *ptr, unsigned short id, unsigned short size)
{
if(size > MAX_FOBJ_SIZE) return false;
bool retb = false;
device_mutex_lock(RT_DEV_LOCK_FLASH);
// SPIC Init
flash_turnon();
if(fspic_isinit == 0) flash_init(&flashobj);
if(_flash_write_cfg(ptr, id, size) >= 0) {
#if DEBUGSOO > 3
DBG_FEEP_INFO("saved ok\n");
#endif
retb = true;
}
SpicDisableRtl8195A();
device_mutex_unlock(RT_DEV_LOCK_FLASH);
return retb;
}
//=============================================================================
//- Прочитать объект из flash -------------------------------------------------
// Параметры:
// prt - указатель, куда сохранить
// id - идентификатор искомого объекта
// maxsize - сколько байт сохранить максимум из найденного объекта, по ptr
// Returns:
// -3 - error
// -2 - flash rd/wr/clr error
// -1 - не найден
// 0..MAX_FOBJ_SIZE - ok, сохраненный размер объекта
//-----------------------------------------------------------------------------
signed short FLASH_EEP_ATTR flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize)
{
signed short rets = FMEM_ERROR;
if (maxsize <= MAX_FOBJ_SIZE) {
device_mutex_lock(RT_DEV_LOCK_FLASH);
fobj_head fobj;
fobj.n.id = id;
fobj.n.size = 0;
#if DEBUGSOO > 2
DBG_FEEP_INFO("read obj id: %04x[%d]\n", id, maxsize);
#endif
// SPIC Init
flash_turnon();
if(fspic_isinit == 0) flash_init(&flashobj);
unsigned int faddr = get_addr_bscfg(false);
if(faddr >= FMEM_ERROR_MAX) {
faddr = get_addr_fobj(faddr, &fobj, false);
if(faddr >= FMEM_ERROR_MAX) {
#if 0
if(maxsize != 0 && ptr != NULL)
copy_align4_to_align1(ptr, SPI_FLASH_BASE + faddr + fobj_head_size, mMIN(fobj.n.size, maxsize));
#else
if(maxsize != 0 && ptr != NULL)
SpicUserReadRtl8195A(mMIN(fobj.n.size, maxsize), faddr + fobj_head_size, ptr, flashobj.SpicInitPara.Mode.BitMode);
#endif
#if DEBUGSOO > 3
DBG_FEEP_INFO("read ok, faddr: %p, size: %d\n", faddr, fobj.n.size);
#endif
rets = fobj.n.size;
}
else {
#if DEBUGSOO > 3
DBG_FEEP_INFO("obj not found\n");
#endif
rets = -faddr-1;
}
}
else rets = -faddr-1;
SpicDisableRtl8195A();
device_mutex_unlock(RT_DEV_LOCK_FLASH);
}
return rets;
}
//=============================================================================

View file

@ -0,0 +1,242 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "pinmap.h"
#if CONFIG_GPIO_EN
#include "hal_gpio.h"
#include "gpio_api.h"
// convert Mbed pin mode to HAL Pin Mode
const u8 GPIO_InPinMode[] = {
DIN_PULL_NONE, // PullNone
DIN_PULL_HIGH, // PullUp
DIN_PULL_LOW, // PullDown
DIN_PULL_NONE // OpenDrain
};
const u8 GPIO_SWPORT_DR_TBL[] = {
GPIO_PORTA_DR,
GPIO_PORTB_DR,
GPIO_PORTC_DR
};
const u8 GPIO_EXT_PORT_TBL[] = {
GPIO_EXT_PORTA,
GPIO_EXT_PORTB,
GPIO_EXT_PORTC
};
const u8 GPIO_SWPORT_DDR_TBL[] = {
GPIO_PORTA_DDR,
GPIO_PORTB_DDR,
GPIO_PORTC_DDR
};
#if 0
void gpio_set_hal_pin_mode(gpio_t *obj)
{
if (obj->direction == PIN_OUTPUT) {
switch (obj->mode) {
case PullNone:
case PullDown:
case PullUp:
obj->hal_pin.pin_mode = DOUT_PUSH_PULL;
break;
case OpenDrain:
obj->hal_pin.pin_mode = DOUT_OPEN_DRAIN;
break;
default:
obj->hal_pin.pin_mode = DOUT_PUSH_PULL;
break;
}
}
else {
switch (obj->mode) {
case PullNone:
case OpenDrain:
obj->hal_pin.pin_mode = DIN_PULL_NONE;
break;
case PullDown:
obj->hal_pin.pin_mode = DIN_PULL_LOW;
break;
case PullUp:
obj->hal_pin.pin_mode = DIN_PULL_HIGH;
break;
default:
obj->hal_pin.pin_mode = DIN_PULL_NONE;
break;
}
}
}
#endif
void gpio_set_hal_pin_mode(gpio_t *obj)
{
uint32_t mode;
mode = obj->mode;
if (obj->direction == PIN_OUTPUT) {
if (mode == OpenDrain) {
obj->hal_pin.pin_mode = DOUT_OPEN_DRAIN;
} else {
obj->hal_pin.pin_mode = DOUT_PUSH_PULL;
}
} else {
if (mode < 4) {
obj->hal_pin.pin_mode = GPIO_InPinMode[mode];
} else {
obj->hal_pin.pin_mode = DIN_PULL_NONE;
}
}
}
uint32_t gpio_set(PinName pin)
{
u32 ip_pin;
//MBED_ASSERT(pin != (PinName)NC);
DBG_ASSERT(pin != (PinName)NC);
pin_function(pin, 0);
ip_pin = HAL_GPIO_GetPinName((u32)pin);
return ip_pin;
}
void gpio_init(gpio_t *obj, PinName pin)
{
uint32_t pin_name;
if (pin == (PinName)NC)
return;
obj->pin = pin;
obj->mode = PullNone;
obj->direction = PIN_INPUT;
pin_name = gpio_set(pin); // get the IP pin name
obj->hal_pin.pin_name = pin_name;
obj->hal_pin.pin_mode = DIN_PULL_NONE;
obj->hal_port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name);
obj->hal_pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name);
HAL_GPIO_Init(&obj->hal_pin);
}
void gpio_mode(gpio_t *obj, PinMode mode)
{
obj->mode = mode;
gpio_set_hal_pin_mode(obj);
HAL_GPIO_Init(&obj->hal_pin);
}
// Initial the Pin direction
void gpio_dir(gpio_t *obj, PinDirection direction) {
// DBG_ASSERT(obj->pin != (PinName)NC);
obj->direction = direction;
gpio_set_hal_pin_mode(obj);
HAL_GPIO_Init(&obj->hal_pin);
}
// Change the pin direction directly
void gpio_change_dir(gpio_t *obj, PinDirection direction) {
uint32_t reg_value;
uint8_t port_num;
uint8_t pin_num;
obj->direction = direction;
gpio_set_hal_pin_mode(obj);
port_num = obj->hal_port_num;
pin_num = obj->hal_pin_num;
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DDR_TBL[port_num]);
if (direction) {
// Out
reg_value |= (1 << pin_num);
} else {
// In
reg_value &= ~(1 << pin_num);
}
HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DDR_TBL[port_num], reg_value);
}
void gpio_write(gpio_t *obj, int value)
{
HAL_GPIO_PIN *hal_pin=&obj->hal_pin;
volatile uint32_t reg_value;
uint8_t port_num;
uint8_t pin_num;
if (hal_pin->pin_mode != DOUT_OPEN_DRAIN) {
port_num = obj->hal_port_num;
pin_num = obj->hal_pin_num;
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num]);
reg_value &= ~(1 << pin_num);
reg_value |= ((value&0x01)<< pin_num);
HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num], reg_value);
} else {
HAL_GPIO_WritePin(&obj->hal_pin, value);
}
}
int gpio_read(gpio_t *obj) {
volatile uint32_t reg_value;
uint8_t port_num;
uint8_t pin_num;
// HAL_GPIO_PIN_STATE pin_status;
HAL_GPIO_PIN_MODE pin_mode;
port_num = obj->hal_port_num;
pin_num = obj->hal_pin_num;
pin_mode = obj->hal_pin.pin_mode;
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_EXT_PORT_TBL[port_num]);
if (pin_mode != DOUT_OPEN_DRAIN) {
return ((reg_value >> pin_num) & 0x01);
} else {
return (!((reg_value >> pin_num) & 0x01));
}
// return pin_status;
}
// This API only works for non-Open-Drain pin
void gpio_direct_write(gpio_t *obj, BOOL value)
{
uint8_t port_num;
uint8_t pin_num;
uint32_t reg_value;
port_num = obj->hal_port_num;
pin_num = obj->hal_pin_num;
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num]);
reg_value &= ~(1 << pin_num);
reg_value |= (value<< pin_num);
HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num], reg_value);
}
void gpio_pull_ctrl(gpio_t *obj, PinMode pull_type)
{
// obj->mode = pull_type;
// gpio_set_hal_pin_mode(obj);
HAL_GPIO_PullCtrl((u32) obj->pin, (u32)pull_type);
}
void gpio_deinit(gpio_t *obj) {
HAL_GPIO_DeInit(&obj->hal_pin);
}
#endif

View file

@ -0,0 +1,145 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "pinmap.h"
//static uint32_t channel_ids[32] = {0};
//static gpio_irq_handler irq_handler;
#if CONFIG_GPIO_EN
#include "gpio_irq_api.h"
#include "gpio_irq_ex_api.h"
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
uint32_t pin_name;
if (pin == NC) return -1;
obj->pin = pin;
pin_name = HAL_GPIO_GetPinName((u32)pin);; // get the IP pin name
obj->hal_pin.pin_name = pin_name;
obj->hal_pin.pin_mode = INT_FALLING; // default use Falling trigger
obj->hal_port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name);
obj->hal_pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name);
HAL_GPIO_Irq_Init(&obj->hal_pin);
HAL_GPIO_UserRegIrq(&obj->hal_pin, (VOID*) handler, (VOID*) id);
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
HAL_GPIO_UserUnRegIrq(&obj->hal_pin);
HAL_GPIO_DeInit(&obj->hal_pin);
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
switch((uint32_t)event) {
case IRQ_RISE:
obj->hal_pin.pin_mode = INT_RISING;
break;
case IRQ_FALL:
obj->hal_pin.pin_mode = INT_FALLING;
break;
case IRQ_LOW:
obj->hal_pin.pin_mode = INT_LOW;
break;
case IRQ_HIGH:
obj->hal_pin.pin_mode = INT_HIGH;
break;
case IRQ_NONE:
// ?
break;
default:
break;
}
// HAL_GPIO_Irq_Init(&obj->hal_pin);
HAL_GPIO_Init_8195a(&obj->hal_pin);
HAL_GPIO_IntCtrl(&obj->hal_pin, enable);
}
void gpio_irq_enable(gpio_irq_t *obj)
{
HAL_GPIO_UnMaskIrq(&obj->hal_pin);
}
void gpio_irq_disable(gpio_irq_t *obj)
{
HAL_GPIO_MaskIrq(&obj->hal_pin);
}
void gpio_irq_deinit(gpio_irq_t *obj)
{
HAL_GPIO_DeInit(&obj->hal_pin);
}
void gpio_irq_pull_ctrl(gpio_irq_t *obj, PinMode pull_type)
{
HAL_GPIO_PullCtrl((u32) obj->pin, (u32)pull_type);
}
void gpio_irq_set_event(gpio_irq_t *obj, gpio_irq_event event)
{
uint32_t reg_value;
uint32_t level_edge;
uint32_t polarity;
uint8_t pin_num;
pin_num = obj->hal_pin_num & 0x1f; // Max 31
switch (event) {
case IRQ_LOW:
level_edge = 0; // level trigger
polarity = 0; // active low
break;
case IRQ_HIGH:
level_edge = 0; // level trigger
polarity = 1; // active high
break;
case IRQ_FALL:
level_edge = 1; // edge trigger
polarity = 0; // active low
break;
case IRQ_RISE:
level_edge = 1; // edge trigger
polarity = 1; // active high
break;
default:
DBG_GPIO_ERR("Unknow Interrupt Trigger Type(%d)\n", event);
return;
}
// Config Level or Edge trigger
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_INT_TYPE);
reg_value &= ~(1 << pin_num);
reg_value |= (level_edge << pin_num);
HAL_WRITE32(GPIO_REG_BASE, GPIO_INT_TYPE, reg_value);
// Config Low active or Gigh active
reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_INT_POLARITY);
reg_value &= ~(1 << pin_num);
reg_value |= (polarity << pin_num);
HAL_WRITE32(GPIO_REG_BASE, GPIO_INT_POLARITY, reg_value);
}
#endif

View file

@ -0,0 +1,39 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#include "mbed_assert.h"
#include "basic_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
uint32_t mask;
uint32_t reg_out_offset;
uint32_t reg_dir_offset;
} gpio_t;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,780 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
//#include "mbed_assert.h"
#include "objects.h"
#include "PinNames.h"
//#include <osdep_api.h>
#include "hal_i2c.h"
#include "i2c_api.h"
#include "ex_api.h"
#if CONFIG_I2C_EN
//#include "cmsis.h"
#include "pinmap.h"
static const PinMap PinMap_I2C_SDA[] = {
{PD_4, RTL_PIN_PERI(I2C0, 0, S0), RTL_PIN_FUNC(I2C0, S0)},
{PH_1, RTL_PIN_PERI(I2C0, 0, S1), RTL_PIN_FUNC(I2C0, S1)},
{PC_8, RTL_PIN_PERI(I2C0, 0, S2), RTL_PIN_FUNC(I2C0, S2)},
{PE_7, RTL_PIN_PERI(I2C0, 0, S3), RTL_PIN_FUNC(I2C0, S3)},
{PC_4, RTL_PIN_PERI(I2C1, 1, S0), RTL_PIN_FUNC(I2C1, S0)},
{PH_3, RTL_PIN_PERI(I2C1, 1, S1), RTL_PIN_FUNC(I2C1, S1)},
{PD_7, RTL_PIN_PERI(I2C1, 1, S2), RTL_PIN_FUNC(I2C1, S2)},
{PB_7, RTL_PIN_PERI(I2C2, 2, S0), RTL_PIN_FUNC(I2C2, S0)},
{PE_1, RTL_PIN_PERI(I2C2, 2, S1), RTL_PIN_FUNC(I2C2, S1)},
{PC_7, RTL_PIN_PERI(I2C2, 2, S2), RTL_PIN_FUNC(I2C2, S2)},
{PB_3, RTL_PIN_PERI(I2C3, 3, S0), RTL_PIN_FUNC(I2C3, S0)},
{PE_3, RTL_PIN_PERI(I2C3, 3, S1), RTL_PIN_FUNC(I2C3, S1)},
{PE_5, RTL_PIN_PERI(I2C3, 3, S2), RTL_PIN_FUNC(I2C3, S2)},
{PD_9, RTL_PIN_PERI(I2C3, 3, S3), RTL_PIN_FUNC(I2C3, S3)},
{NC, NC, 0}
};
static const PinMap PinMap_I2C_SCL[] = {
{PD_5, RTL_PIN_PERI(I2C0, 0, S0), RTL_PIN_FUNC(I2C0, S0)},
{PH_0, RTL_PIN_PERI(I2C0, 0, S1), RTL_PIN_FUNC(I2C0, S1)},
{PC_9, RTL_PIN_PERI(I2C0, 0, S2), RTL_PIN_FUNC(I2C0, S2)},
{PE_6, RTL_PIN_PERI(I2C0, 0, S3), RTL_PIN_FUNC(I2C0, S3)},
{PC_5, RTL_PIN_PERI(I2C1, 1, S0), RTL_PIN_FUNC(I2C1, S0)},
{PH_2, RTL_PIN_PERI(I2C1, 1, S1), RTL_PIN_FUNC(I2C1, S1)},
{PD_6, RTL_PIN_PERI(I2C1, 1, S2), RTL_PIN_FUNC(I2C1, S2)},
{PB_6, RTL_PIN_PERI(I2C2, 2, S0), RTL_PIN_FUNC(I2C2, S0)},
{PE_0, RTL_PIN_PERI(I2C2, 2, S1), RTL_PIN_FUNC(I2C2, S1)},
{PC_6, RTL_PIN_PERI(I2C2, 2, S2), RTL_PIN_FUNC(I2C2, S2)},
{PB_2, RTL_PIN_PERI(I2C3, 3, S0), RTL_PIN_FUNC(I2C3, S0)},
{PE_2, RTL_PIN_PERI(I2C3, 3, S1), RTL_PIN_FUNC(I2C3, S1)},
{PE_4, RTL_PIN_PERI(I2C3, 3, S2), RTL_PIN_FUNC(I2C3, S2)},
{PD_8, RTL_PIN_PERI(I2C3, 3, S3), RTL_PIN_FUNC(I2C3, S3)},
{NC, NC, 0}
};
static uint16_t i2c_target_addr[4];
static SAL_I2C_TRANSFER_BUF i2ctxtranbuf[4];
static SAL_I2C_TRANSFER_BUF i2crxtranbuf[4];
extern u32 ConfigDebugErr;
extern u32 ConfigDebuginfo;
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
uint32_t i2c_sel;
uint32_t i2c_idx;
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_USERCB_ADPT pSalI2CUserCBAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
// Determine the I2C to use
uint32_t i2c_sda = (uint32_t)pinmap_peripheral(sda, PinMap_I2C_SDA);
uint32_t i2c_scl = (uint32_t)pinmap_peripheral(scl, PinMap_I2C_SCL);
ConfigDebugErr &= (~(_DBG_I2C_|_DBG_GDMA_));
ConfigDebugInfo&= (~(_DBG_I2C_|_DBG_GDMA_));
i2c_sel = (uint32_t)pinmap_merge(i2c_sda, i2c_scl);
i2c_idx = RTL_GET_PERI_IDX(i2c_sel);
if (unlikely(i2c_idx == NC)) {
DBG_8195A("%s: Cannot find matched port i2c\n", __FUNCTION__);
return;
}
//DBG_8195A("i2c_sel:%x\n",i2c_sel);
//DBG_8195A("i2c_idx:%x\n",i2c_idx);
/* Get I2C device handler */
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&(obj->SalI2CUserCBAdpt);
/*To assign the rest pointers*/
pSalI2CMngtAdpt->MstRDCmdCnt = 0;
pSalI2CMngtAdpt->InnerTimeOut = 2000; // inner time-out count, 2000 ms
pSalI2CMngtAdpt->pSalHndPriv = &(obj->SalI2CHndPriv);
pSalI2CMngtAdpt->pSalHndPriv->ppSalI2CHnd = (void**)&(pSalI2CMngtAdpt->pSalHndPriv);
/* To assign the default (ROM) HAL OP initialization function */
#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT)
pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_Patch;
#elif defined(CONFIG_CHIP_E_CUT)
pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_V04;
#endif
/* To assign the default (ROM) HAL GDMA OP initialization function */
pSalI2CMngtAdpt->pHalGdmaOpInit = HalGdmaOpInit;
/* To assign the default (ROM) SAL interrupt function */
#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT)
pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_Patch;
#elif defined(CONFIG_CHIP_E_CUT)
pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_V04;
#endif
/* To assign the default (ROM) SAL DMA TX interrupt function */
pSalI2CMngtAdpt->pSalDMATxIrqFunc = I2CTXGDMAISRHandle;
/* To assign the default (ROM) SAL DMA RX interrupt function */
pSalI2CMngtAdpt->pSalDMARxIrqFunc = I2CRXGDMAISRHandle;
pSalI2CMngtAdpt->pHalInitDat = &(obj->HalI2CInitData);
pSalI2CMngtAdpt->pHalOp = &(obj->HalI2COp);
pSalI2CMngtAdpt->pIrqHnd = &(obj->I2CIrqHandleDat);
pSalI2CMngtAdpt->pHalTxGdmaAdp = &(obj->HalI2CTxGdmaAdpt);
pSalI2CMngtAdpt->pHalRxGdmaAdp = &(obj->HalI2CRxGdmaAdpt);
pSalI2CMngtAdpt->pHalGdmaOp = &(obj->HalI2CGdmaOp);
pSalI2CMngtAdpt->pIrqTxGdmaHnd = &(obj->I2CTxGdmaIrqHandleDat);
pSalI2CMngtAdpt->pIrqRxGdmaHnd = &(obj->I2CRxGdmaIrqHandleDat);
pSalI2CMngtAdpt->pUserCB = &(obj->SalI2CUserCB);
pSalI2CMngtAdpt->pDMAConf = &(obj->SalI2CDmaUserDef);
/* Assign the private SAL handle to public SAL handle */
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
/* Assign the internal HAL initial data pointer to the SAL handle */
pSalI2CHND->pInitDat = pSalI2CMngtAdpt->pHalInitDat;
/* Assign the internal user callback pointer to the SAL handle */
pSalI2CHND->pUserCB = pSalI2CMngtAdpt->pUserCB;
/* Assign the internal user define DMA configuration to the SAL handle */
pSalI2CHND->pDMAConf = pSalI2CMngtAdpt->pDMAConf;
/*To assign user callback pointers*/
pSalI2CMngtAdpt->pUserCB->pTXCB = pSalI2CUserCBAdpt;
pSalI2CMngtAdpt->pUserCB->pTXCCB = (pSalI2CUserCBAdpt+1);
pSalI2CMngtAdpt->pUserCB->pRXCB = (pSalI2CUserCBAdpt+2);
pSalI2CMngtAdpt->pUserCB->pRXCCB = (pSalI2CUserCBAdpt+3);
pSalI2CMngtAdpt->pUserCB->pRDREQCB = (pSalI2CUserCBAdpt+4);
pSalI2CMngtAdpt->pUserCB->pERRCB = (pSalI2CUserCBAdpt+5);
pSalI2CMngtAdpt->pUserCB->pDMATXCB = (pSalI2CUserCBAdpt+6);
pSalI2CMngtAdpt->pUserCB->pDMATXCCB = (pSalI2CUserCBAdpt+7);
pSalI2CMngtAdpt->pUserCB->pDMARXCB = (pSalI2CUserCBAdpt+8);
pSalI2CMngtAdpt->pUserCB->pDMARXCCB = (pSalI2CUserCBAdpt+9);
pSalI2CMngtAdpt->pUserCB->pGENCALLCB= (pSalI2CUserCBAdpt+10);
/* Set I2C Device Number */
pSalI2CHND->DevNum = i2c_idx;
/* Load I2C default value */
RtkI2CLoadDefault(pSalI2CHND);
/* Assign I2C Pin Mux */
pSalI2CHND->PinMux = RTL_GET_PERI_SEL(i2c_sel);
pSalI2CHND->OpType = I2C_INTR_TYPE;
pSalI2CHND->I2CMaster = I2C_MASTER_MODE;
pSalI2CHND->I2CSpdMod = I2C_SS_MODE;
pSalI2CHND->I2CClk = 100;
pSalI2CHND->I2CAckAddr = 0;
pSalI2CHND->TimeOut = 300;
pSalI2CHND->AddRtyTimeOut = 3000;
pSalI2CHND->I2CExd |= (I2C_EXD_MTR_ADDR_RTY);
pSalI2CMngtAdpt->InnerTimeOut = pSalI2CHND->TimeOut;
/* Deinit I2C first */
//i2c_reset(obj);
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
void i2c_frequency(i2c_t *obj, int hz) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
uint16_t i2c_default_clk = (uint16_t) pSalI2CHND->I2CClk;
uint16_t i2c_user_clk = (uint16_t) (hz/1000);
if (i2c_default_clk != i2c_user_clk) {
/* Deinit I2C first */
i2c_reset(obj);
if (i2c_user_clk <= 100) {
pSalI2CHND->I2CSpdMod = I2C_SS_MODE;
}
else if ((i2c_user_clk > 100) && (i2c_user_clk <= 400)) {
pSalI2CHND->I2CSpdMod = I2C_FS_MODE;
}
else if (i2c_user_clk > 400) {
pSalI2CHND->I2CSpdMod = I2C_HS_MODE;
}
else {
pSalI2CHND->I2CSpdMod = I2C_SS_MODE;
}
/* Load the user defined I2C clock */
pSalI2CHND->I2CClk = i2c_user_clk;
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
}
inline int i2c_start(i2c_t *obj) {
return 0;
}
inline int i2c_stop(i2c_t *obj) {
return 0;
}
// extern u32 HalDelayUs(IN u32 us);
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
u32 I2CInTOTcnt = 0;
u32 InTimeoutCount = 0;
u32 InStartCount = 0;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
if (i2c_target_addr[pSalI2CHND->DevNum] != address) {
/* Deinit I2C first */
i2c_reset(obj);
/* Load the user defined I2C target slave address */
i2c_target_addr[pSalI2CHND->DevNum] = address;
pSalI2CHND->I2CAckAddr = address;
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
/* Check if the it's the last byte or not */
pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS);
if (!stop) {
pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS;
}
pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pRXBuf->DataLen = length;
pSalI2CHND->pRXBuf->TargetAddr= pSalI2CHND->I2CAckAddr;
pSalI2CHND->pRXBuf->RegAddr = 0;
pSalI2CHND->pRXBuf->pDataBuf = (u8 *)data;
if (RtkI2CReceive(pSalI2CHND) != HAL_OK) {
length = length - pSalI2CHND->pRXBuf->DataLen;
return ((int)length);
}
else {
//DBG_8195A(">\n");
/* Calculate user time out parameters */
I2CInTOTcnt = 300;
if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) {
InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US);
InStartCount = HalTimerOp.HalTimerReadCount(1);
}
while((pSalI2CHND->DevSts != I2C_STS_IDLE) &&
(pSalI2CHND->DevSts != I2C_STS_ERROR) &&
(pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) {
/* Time-Out check */
if (InTimeoutCount > 0) {
if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO;
/* DeInit I2C, Init I2C */
//RtkI2CDeInit(pSalI2CHND);
//HalDelayUs(1000);
//RtkI2CInit(pSalI2CHND);
return ((int)(length));
}
}
else {
if (I2CInTOTcnt == 0) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO;
/* DeInit I2C, Init I2C */
//RtkI2CDeInit(pSalI2CHND);
//RtkI2CInit(pSalI2CHND);
return ((int)(length));
}
}
}
//DBG_8195A("<\n");
if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)
return ((int)(length - pSalI2CHND->pRXBuf->DataLen));
else
return ((int)(length));
}
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
u32 I2CInTOTcnt = 0;
u32 InTimeoutCount = 0;
u32 InStartCount = 0;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
if (i2c_target_addr[pSalI2CHND->DevNum] != address) {
/* Deinit I2C first */
i2c_reset(obj);
/* Load the user defined I2C target slave address */
i2c_target_addr[pSalI2CHND->DevNum] = address;
pSalI2CHND->I2CAckAddr = address;
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
/* Check if the it's the last byte or not */
pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS);
if (!stop) {
pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS;
}
pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pTXBuf->DataLen = length;
pSalI2CHND->pTXBuf->TargetAddr= pSalI2CHND->I2CAckAddr;
pSalI2CHND->pTXBuf->RegAddr = 0;
pSalI2CHND->pTXBuf->pDataBuf = (u8 *)data;
if (RtkI2CSend(pSalI2CHND) != HAL_OK) {
length = length - pSalI2CHND->pTXBuf->DataLen;
return ((int)length);
}
else {
//DBG_8195A("(\n");
/* Calculate user time out parameters */
I2CInTOTcnt = 300;
if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) {
InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US);
InStartCount = HalTimerOp.HalTimerReadCount(1);
}
while((pSalI2CHND->DevSts != I2C_STS_IDLE) &&
(pSalI2CHND->DevSts != I2C_STS_ERROR) &&
(pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) {
/* Time-Out check */
if (InTimeoutCount > 0) {
if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO;
/* DeInit I2C, Init I2C */
//RtkI2CDeInit(pSalI2CHND);
//RtkI2CInit(pSalI2CHND);
return ((int)(length));
}
}
else {
if (I2CInTOTcnt == 0) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO;
/* DeInit I2C, Init I2C */
//RtkI2CDeInit(pSalI2CHND);
//RtkI2CInit(pSalI2CHND);
return ((int)(length));
}
}
}
if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)
return ((int)(length - pSalI2CHND->pTXBuf->DataLen));
else
return ((int)(length));
}
}
int i2c_byte_read(i2c_t *obj, int last) {
uint8_t i2cdatlocal;
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
/* Check if the it's the last byte or not */
pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS);
if (!last) {
pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS;
}
pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pRXBuf->DataLen = 1;
pSalI2CHND->pRXBuf->TargetAddr= pSalI2CHND->I2CAckAddr;
pSalI2CHND->pRXBuf->RegAddr = 0;
pSalI2CHND->pRXBuf->pDataBuf = &i2cdatlocal;
RtkI2CReceive(pSalI2CHND);
return (int)i2cdatlocal;
}
int i2c_byte_write(i2c_t *obj, int data) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS);
pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS;
pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pTXBuf->DataLen = 1;
pSalI2CHND->pTXBuf->TargetAddr= pSalI2CHND->I2CAckAddr;
pSalI2CHND->pTXBuf->RegAddr = 0;
pSalI2CHND->pTXBuf->pDataBuf = (unsigned char*)&data;
if (RtkI2CSend(pSalI2CHND) != HAL_OK) {
return 0;
}
return 1;
}
void i2c_reset(i2c_t *obj) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
/* Deinit I2C directly */
RtkI2CDeInitForPS(pSalI2CHND);
}
void i2c_restart_enable(i2c_t *obj) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
uint32_t i2clocaltmp;
uint8_t i2cen;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
i2cen = pSalI2CHND->pInitDat->I2CEn;
if (i2cen == I2C_ENABLE) {
pSalI2CHND->pInitDat->I2CEn = I2C_DISABLE;
pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat);
}
i2clocaltmp = HalI2CRead32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON);
i2clocaltmp |= BIT_IC_CON_IC_RESTART_EN;
HalI2CWrite32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON, i2clocaltmp);
if (i2cen == I2C_ENABLE) {
pSalI2CHND->pInitDat->I2CEn = I2C_ENABLE;
pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat);
}
pSalI2CHND->pInitDat->I2CReSTR = I2C_ENABLE;
}
void i2c_restart_disable(i2c_t *obj) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
uint32_t i2clocaltmp;
uint8_t i2cen;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
i2cen = pSalI2CHND->pInitDat->I2CEn;
if (i2cen == I2C_ENABLE) {
pSalI2CHND->pInitDat->I2CEn = I2C_DISABLE;
pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat);
}
i2clocaltmp = HalI2CRead32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON);
i2clocaltmp &= (~BIT_IC_CON_IC_RESTART_EN);
HalI2CWrite32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON, i2clocaltmp);
if (i2cen == I2C_ENABLE) {
pSalI2CHND->pInitDat->I2CEn = I2C_ENABLE;
pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat);
}
pSalI2CHND->pInitDat->I2CReSTR = I2C_DISABLE;
}
void i2c_set_user_callback(i2c_t *obj, I2CCallback i2ccb, void(*i2c_callback)(void *)) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
if ((i2ccb >= I2C_TX_COMPLETE) && (i2ccb <= I2C_ERR_OCCURRED)) {
switch (i2ccb) {
case I2C_TX_COMPLETE:
pSalI2CHND->pUserCB->pTXCCB->USERCB = i2c_callback;
break;
case I2C_RX_COMPLETE:
pSalI2CHND->pUserCB->pRXCCB->USERCB = i2c_callback;
break;
case I2C_RD_REQ_COMMAND:
pSalI2CHND->pUserCB->pRDREQCB->USERCB = i2c_callback;
break;
case I2C_ERR_OCCURRED:
pSalI2CHND->pUserCB->pERRCB->USERCB = i2c_callback;
break;
default:
break;
}
}
}
void i2c_clear_user_callback(i2c_t *obj, I2CCallback i2ccb) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
if ((i2ccb >= I2C_TX_COMPLETE) && (i2ccb <= I2C_ERR_OCCURRED)) {
switch (i2ccb) {
case I2C_TX_COMPLETE:
pSalI2CHND->pUserCB->pTXCCB = NULL;
break;
case I2C_RX_COMPLETE:
pSalI2CHND->pUserCB->pRXCCB = NULL;
break;
case I2C_ERR_OCCURRED:
pSalI2CHND->pUserCB->pERRCB = NULL;
break;
default:
break;
}
}
}
int i2c_enable_control(i2c_t *obj, int enable) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pSalI2CHND->pInitDat->I2CEn = enable;
pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat);
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
uint16_t i2c_default_addr = (uint16_t) pSalI2CHND->I2CAckAddr;
uint16_t i2c_user_addr = (uint16_t) address;
if (i2c_default_addr != i2c_user_addr) {
/* Deinit I2C first */
i2c_reset(obj);
/* Load the user defined I2C clock */
pSalI2CHND->I2CAckAddr = i2c_user_addr;
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
}
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
/* Deinit I2C first */
i2c_reset(obj);
/* Load the user defined I2C clock */
pSalI2CHND->I2CMaster = I2C_MASTER_MODE;
if (enable_slave)
pSalI2CHND->I2CMaster = I2C_SLAVE_MODE;
/* Init I2C now */
RtkI2CInitForPS(pSalI2CHND);
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) {
int i2cslvrevsts = NoData;
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
i2cslvrevsts = RtkSalI2CSts(pSalI2CHND);
return i2cslvrevsts;
}
int i2c_slave_read(i2c_t *obj, char *data, int length) {
u32 I2CInTOTcnt = 0;
u32 InTimeoutCount = 0;
u32 InStartCount = 0;
//uint8_t i2cdatlocal;
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pRXBuf->DataLen = length;
pSalI2CHND->pRXBuf->pDataBuf = (u8 *)data;
if (RtkI2CReceive(pSalI2CHND) != HAL_OK) {
return 0; //error
}
else {
/* Calculate user time out parameters */
I2CInTOTcnt = 300;
if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) {
InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US);
InStartCount = HalTimerOp.HalTimerReadCount(1);
}
while((pSalI2CHND->DevSts != I2C_STS_IDLE) &&
(pSalI2CHND->DevSts != I2C_STS_ERROR) &&
(pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) {
/* Time-Out check */
if (InTimeoutCount > 0) {
if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO;
return ((int)(length));
}
}
else {
if (I2CInTOTcnt == 0) {
pSalI2CHND->DevSts = I2C_STS_TIMEOUT;
pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO;
return ((int)(length));
}
}
}
if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)
return ((int)(length - pSalI2CHND->pTXBuf->DataLen));
else
return ((int)(length));
}
}
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum];
pSalI2CHND->pTXBuf->DataLen = length;
//obj->i2c->pTXBuf->TargetAddr= obj->i2c->I2CAckAddr;
//obj->i2c->pTXBuf->RegAddr = 0;
pSalI2CHND->pTXBuf->pDataBuf = (u8 *)data;
if (RtkI2CSend(pSalI2CHND) != HAL_OK) {
return 0; //error
}
return 1;
}
/** \brief Description of i2c_slave_set_for_rd_req
*
* i2c_slave_set_for_rd_req is used to set/clear i2c slave RD_REQ interrupt mask.
* If RD_REQ interrupt is set, slave could invoke read request callback when it gets
* a read command from other i2c master.
*
* \param i2c_t *obj : i2c object
* \param int set : set or clear for read request. Once it's set, i2c would invoke read request callback when a
* read command is sent to it.
* \return result
*/
int i2c_slave_set_for_rd_req(i2c_t *obj, int set) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL;
PHAL_I2C_OP pHalI2COP = NULL;
u32 I2CLocalTemp;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat;
pHalI2COP = pSalI2CMngtAdpt->pHalOp;
I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK);
if (set) {
I2CLocalTemp |= BIT_IC_INTR_MASK_M_RD_REQ;
} else {
I2CLocalTemp &= (~BIT_IC_INTR_MASK_M_RD_REQ);
}
pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp;
pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat);
return 1;
}
/** \brief Description of i2c_slave_set_for_data_nak
*
* i2c_slave_set_for_data_nak is used to set/clear i2c slave NAK or ACK data part in transfer.
*
* \param i2c_t *obj : i2c object
* \param int set : set or clear for data NAK.
* \return result
*/
int i2c_slave_set_for_data_nak(i2c_t *obj, int set_nak) {
PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL;
PSAL_I2C_HND pSalI2CHND = NULL;
PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL;
PHAL_I2C_OP pHalI2COP = NULL;
u32 I2CLocalTemp;
pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt);
pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv);
pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat;
pHalI2COP = pSalI2CMngtAdpt->pHalOp;
I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS);
//if (set_nak) {
while (BIT_IC_STATUS_SLV_ACTIVITY & I2CLocalTemp) {
I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS);
}
//}
HAL_I2C_WRITE32(pSalI2CHND->DevNum, REG_DW_I2C_IC_SLV_DATA_NACK_ONLY, set_nak);
}
#endif // CONFIG_I2C_SLAVE_EN
#endif // CONFIG_I2C_EN

View file

@ -0,0 +1,247 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "i2s_api.h"
#include "pinmap.h"
#if CONFIG_I2S_EN
static const PinMap PinMap_I2S_TX[] = {
{PE_2, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710
{PH_2, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)},
{PD_2, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)},
{PC_7, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)},
{PC_2, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710
{PD_6, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)},
{PE_6, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)},
{NC, NC, 0}
};
static const PinMap PinMap_I2S_RX[] = {
{PH_5, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)},
{PC_5, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)}, //+RTL8710
{PC_4, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710
{PD_3, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)},
{PE_8, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S1)},
{NC, NC, 0}
};
static const PinMap PinMap_I2S_CLK[] = {
{PE_1, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710
{PH_1, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)},
{PD_1, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)},
{PC_8, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)},
{PC_1, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710
{PD_5, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)},
{PE_5, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)},
{NC, NC, 0}
};
static const PinMap PinMap_I2S_WS[] = {
{PE_0, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710
{PH_0, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)},
{PD_0, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)},
{PC_9, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)},
{PC_0, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710
{PD_4, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)},
{PE_4, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)}, //+RTL8710
{NC, NC, 0}
};
static const HAL_I2S_DEF_SETTING I2SDefaultSetting = {
.I2SMaster = I2S_MASTER_MODE, //I2S Function Mode
.DevSts = I2S_STS_UNINITIAL, //I2S device status
.I2SChNum = I2S_CH_STEREO, //I2S Channel number mono or stereo
.I2SPageNum = I2S_4PAGE, //I2S Page number 2~4
.I2STRxAct = I2S_TXRX, //I2S tx rx act, tx only or rx only or tx+rx
.I2SWordLen = I2S_WL_16, //I2S Word length 16bit or 24bit
.I2SPageSize = (768/4)-1, //I2S Page size 1~4096 word
.I2SRate = I2S_SR_48KHZ, //I2S sample rate 8k ~ 96khz
.I2STxIntrMSK = I2S_TX_INT_PAGE0_OK|I2S_TX_INT_PAGE1_OK| \
I2S_TX_INT_PAGE2_OK|I2S_TX_INT_PAGE3_OK, /*I2S Tx Interrupt Mask*/
.I2SRxIntrMSK = I2S_RX_INT_PAGE0_OK|I2S_RX_INT_PAGE1_OK| \
I2S_RX_INT_PAGE2_OK|I2S_RX_INT_PAGE3_OK /*I2S Rx Interrupt Mask*/
};
void i2s_init(i2s_t *obj, PinName sck, PinName ws, PinName sd)
{
uint32_t i2s_sck, i2s_ws, i2s_tx, i2s_rx;
uint32_t i2s_sel;;
uint8_t i2s_idx;
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
HAL_Status ret;
// Determine the UART to use (UART0, UART1, or UART3)
i2s_sck = pinmap_peripheral(sck, PinMap_I2S_CLK);
i2s_ws = pinmap_peripheral(ws, PinMap_I2S_WS);
i2s_tx = pinmap_find_peripheral(sd, PinMap_I2S_TX);
i2s_rx = pinmap_find_peripheral(sd, PinMap_I2S_RX);
i2s_sel = pinmap_merge(i2s_sck, i2s_ws);
if (unlikely(i2s_sel == NC)) {
DBG_I2S_ERR("%s: Cannot find matched I2S for given pin\n", __FUNCTION__);
return;
}
if( (i2s_sel != i2s_tx) && (i2s_sel != i2s_rx)){
DBG_I2S_ERR("%s: Cannot find matched I2S for given pin\n", __FUNCTION__);
return;
}
i2s_idx = RTL_GET_PERI_IDX(i2s_sel);
pI2SAdapter->DevNum = i2s_idx;
pI2SAdapter->PinMux = RTL_GET_PERI_SEL(i2s_sel);;
DBG_I2S_INFO("%s: Use I2S%d Sel%d\r\n", __FUNCTION__, pI2SAdapter->DevNum, pI2SAdapter->PinMux);
pI2SAdapter->pInitDat = &obj->InitDat;
RtkI2SLoadDefault(pI2SAdapter, (VOID*)&I2SDefaultSetting);
// Load user defined parameters
pI2SAdapter->pInitDat->I2SChNum = obj->channel_num;
pI2SAdapter->pInitDat->I2SRate = obj->sampling_rate;
pI2SAdapter->pInitDat->I2SWordLen = obj->word_length;
pI2SAdapter->pInitDat->I2STRxAct = obj->direction;
//RtkI2SInit(pI2SAdapter);
ret = HalI2SInit(pI2SAdapter);
if(ret != HAL_OK){
DBG_I2S_ERR("%s: HalI2SInit is failure\n", __FUNCTION__);
}
}
void i2s_set_dma_buffer(i2s_t *obj, char *tx_buf, char *rx_buf,
uint32_t page_num, uint32_t page_size)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
u32 i;
if ((page_num < 2) || (page_num > 4) || (page_size < 8)) {
DBG_I2S_INFO("%s: PageNum(%d) valid value is 2~4; PageSize(%d must > 8)\r\n", \
__FUNCTION__, page_num, page_size);
return;
}
pI2SAdapter->pInitDat->I2SPageNum = page_num - 1;
pI2SAdapter->pInitDat->I2SPageSize = page_size/4 - 1; // unit is 4-bytes
pI2SAdapter->pInitDat->I2STxData = (u8*)tx_buf;
pI2SAdapter->pInitDat->I2SRxData = (u8*)rx_buf;
HalI2SSetDMABuf(pI2SAdapter->pInitDat);
for (i=0;i<page_num;i++) {
pI2SAdapter->TxPageList[i] = (uint32_t*)(tx_buf + ((page_size) * i));
pI2SAdapter->RxPageList[i] = (uint32_t*)(rx_buf + ((page_size) * i));
}
}
void i2s_tx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
pI2SAdapter->UserCB.TxCCB = handler;
pI2SAdapter->UserCB.TxCBId = id;
}
void i2s_rx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
pI2SAdapter->UserCB.RxCCB = handler;
pI2SAdapter->UserCB.RxCBId = id;
}
void i2s_set_direction(i2s_t *obj, int trx_type)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
obj->direction = trx_type;
pI2SAdapter->pInitDat->I2STRxAct = trx_type;
HalI2SSetDirection(pI2SAdapter->pInitDat);
}
void i2s_set_param(i2s_t *obj, int channel_num, int rate, int word_len)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
obj->channel_num = channel_num;
obj->sampling_rate = rate;
obj->word_length = word_len;
pI2SAdapter->pInitDat->I2SChNum = channel_num;
pI2SAdapter->pInitDat->I2SRate = rate;
pI2SAdapter->pInitDat->I2SWordLen = word_len;
HalI2SSetChNum(pI2SAdapter->pInitDat);
HalI2SSetRate(pI2SAdapter->pInitDat);
HalI2SSetWordLen(pI2SAdapter->pInitDat);
}
void i2s_deinit(i2s_t *obj)
{
//RtkI2SDeInit((VOID*)&obj->I2SAdapter);
HalI2SDeInit((VOID*)&obj->I2SAdapter);
}
int* i2s_get_tx_page(i2s_t *obj)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
u8 page_idx;
page_idx = HalI2SGetTxPage((VOID*)pI2SAdapter->pInitDat);
if (page_idx <= pI2SAdapter->pInitDat->I2SPageNum) {
return ((int*)pI2SAdapter->TxPageList[page_idx]);
} else {
return NULL;
}
}
void i2s_send_page(i2s_t *obj, uint32_t *pbuf)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
u32 page_num, i;
page_num = pI2SAdapter->pInitDat->I2SPageNum + 1;
for (i=0;i<page_num;i++) {
if (pI2SAdapter->TxPageList[i] == pbuf) {
HalI2SPageSend(pI2SAdapter->pInitDat, i);
break; // break the for loop
}
}
if (i == page_num) {
DBG_I2S_ERR("i2s_send_page: the pbuf(0x%x) is not a DMA buffer\r\n", pbuf);
}
}
void i2s_recv_page(i2s_t *obj)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
HalI2SPageRecv(pI2SAdapter->pInitDat);
}
void i2s_enable(i2s_t *obj)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
//RtkI2SEnable(pI2SAdapter);
HalI2SEnable(pI2SAdapter);
}
void i2s_disable(i2s_t *obj)
{
PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter;
//RtkI2SDisable(pI2SAdapter);
HalI2SDisable(pI2SAdapter);
}
#endif // end of "#if CONFIG_I2S_EN"

View file

@ -0,0 +1,510 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "log_uart_api.h"
#include <string.h>
const u32 log_uart_support_rate[] = {
UART_BAUD_RATE_2400, UART_BAUD_RATE_4800, UART_BAUD_RATE_9600,
UART_BAUD_RATE_19200, UART_BAUD_RATE_38400, UART_BAUD_RATE_57600,
UART_BAUD_RATE_115200, UART_BAUD_RATE_921600, UART_BAUD_RATE_1152000,
0xFFFFFFFF
};
extern HAL_TIMER_OP HalTimerOp;
extern u32 ConfigDebugErr;
extern u32 ConfigDebugWarn;
extern u32 ConfigDebugInfo;
extern u32 CfgSysDebugErr;
extern u32 CfgSysDebugInfo;
extern u32 CfgSysDebugWarn;
extern HAL_Status RuartIsTimeout (u32 StartCount, u32 TimeoutCnt);
extern u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartIrqHandle(VOID * Data);
int32_t log_uart_init (log_uart_t *obj, int baudrate, int data_bits, SerialParity parity, int stop_bits)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
int i;
_memset((void*)obj, 0, sizeof(log_uart_t));
pUartAdapter = &obj->log_hal_uart;
// Check Baud rate
for (i=0; log_uart_support_rate[i]!=0xFFFFFF; i++) {
if (log_uart_support_rate[i] == baudrate) {
break;
}
}
if (log_uart_support_rate[i]== 0xFFFFFF) {
DBG_UART_ERR("log_uart_init: Not support Baud Rate %d\n", baudrate);
return -1;
}
// check word width
if ((data_bits < 5) || (data_bits > 8)) {
DBG_UART_ERR("log_uart_init: Not support Word Width %d\n", data_bits);
return -1;
}
//4 Inital Log uart
pUartAdapter->BaudRate = baudrate;
pUartAdapter->DataLength = data_bits-5;
pUartAdapter->FIFOControl = FCR_FIFO_EN | FCR_TX_TRIG_HF | FCR_RX_TRIG_HF;
// only enable Rx linstatus at initial,
// Tx & Rx interrupt will be enabled @ transfer start time
pUartAdapter->IntEnReg = IER_ELSI;
switch (parity) {
case ParityNone:
pUartAdapter->Parity = LCR_PARITY_NONE;
break;
case ParityOdd:
pUartAdapter->Parity = LCR_PARITY_ODD;
break;
case ParityEven:
pUartAdapter->Parity = LCR_PARITY_EVEN;
break;
default:
DBG_UART_ERR("log_uart_init: Not support parity type %d\n", parity);
return -1;
}
if (stop_bits > 1) {
// if width is 5 bits, stop bit will be 1.5 bit
pUartAdapter->Stop = LCR_STOP_2B;
} else {
pUartAdapter->Stop = LCR_STOP_1B;
}
//4 Initial Log Uart
HalLogUartInitSetting(pUartAdapter);
// disable all debug message
ConfigDebugErr = 0;
ConfigDebugWarn = 0;
ConfigDebugInfo = 0;
CfgSysDebugErr = 0;
CfgSysDebugInfo = 0;
CfgSysDebugWarn = 0;
return 0;
}
void log_uart_free(log_uart_t *obj)
{
LOG_UART_ADAPTER UartAdapter;
// Recover the Log UART for debug message printing
//4 Release log uart reset and clock
LOC_UART_FCTRL(OFF);
LOC_UART_FCTRL(ON);
ACTCK_LOG_UART_CCTRL(ON);
//4 Inital Log uart
UartAdapter.BaudRate = DEFAULT_BAUDRATE;
UartAdapter.DataLength = UART_DATA_LEN_8BIT;
UartAdapter.FIFOControl = 0xC1;
UartAdapter.IntEnReg = 0x00;
UartAdapter.Parity = UART_PARITY_DISABLE;
UartAdapter.Stop = UART_STOP_1BIT;
// un_register current IRQ first
InterruptUnRegister(&(obj->log_hal_uart.IrqHandle));
//4 Initial Log Uart
HalLogUartInit(UartAdapter);
}
void log_uart_baud(log_uart_t *obj, int baudrate)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
int i;
pUartAdapter = &obj->log_hal_uart;
// Check Baud rate
for (i=0; log_uart_support_rate[i]!=0xFFFFFFFF; i++) {
if (log_uart_support_rate[i] == baudrate) {
break;
}
}
if (log_uart_support_rate[i]== 0xFFFFFF) {
DBG_UART_ERR("log_uart_baud: Not support Baud Rate %d\n", baudrate);
return;
}
pUartAdapter->BaudRate = baudrate;
HalLogUartSetBaudRate(pUartAdapter);
}
void log_uart_format(log_uart_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
pUartAdapter = &obj->log_hal_uart;
// check word width
if ((data_bits < 5) || (data_bits > 8)) {
DBG_UART_ERR("log_uart_format: Not support Word Width %d\n", data_bits);
return;
}
//4 Inital Log uart
pUartAdapter->DataLength = data_bits - 5;
switch (parity) {
case ParityNone:
pUartAdapter->Parity = LCR_PARITY_NONE;
break;
case ParityOdd:
pUartAdapter->Parity = LCR_PARITY_ODD;
break;
case ParityEven:
pUartAdapter->Parity = LCR_PARITY_EVEN;
break;
default:
DBG_UART_ERR("log_uart_format: Not support parity type %d\n", parity);
return;
}
if (stop_bits > 1) {
// if width is 5 bits, stop bit will be 1.5 bit
pUartAdapter->Stop = LCR_STOP_2B;
} else {
pUartAdapter->Stop = LCR_STOP_1B;
}
HalLogUartSetLineCtrl(pUartAdapter);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
void log_uart_irq_handler(log_uart_t *obj, loguart_irq_handler handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
pUartAdapter = &(obj->log_hal_uart);
pUartAdapter->api_irq_handler = handler;
pUartAdapter->api_irq_id = id;
}
void log_uart_irq_set(log_uart_t *obj, LOG_UART_INT_ID irq, uint32_t enable)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
u8 int_en=0;
pUartAdapter = &(obj->log_hal_uart);
switch (irq) {
case IIR_RX_RDY:
int_en = IER_ERBFI;
break;
case IIR_THR_EMPTY:
int_en = IER_ETBEI;
break;
case IIR_RX_LINE_STATUS:
int_en = IER_ELSI;
break;
case IIR_MODEM_STATUS:
int_en = IER_EDSSI;
break;
default:
DBG_UART_WARN("log_uart_irq_set: Unknown Irq Id\n");
return;
}
if (enable) {
pUartAdapter->IntEnReg |= int_en;
} else {
// disable
pUartAdapter->IntEnReg &= (~int_en);
}
HalLogUartSetIntEn(pUartAdapter);
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
char log_uart_getc(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
while (!log_uart_readable(obj));
return (char)(HAL_UART_READ32(UART_REV_BUF_OFF) & 0xFF);
}
void log_uart_putc(log_uart_t *obj, char c)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
while (!log_uart_writable(obj));
HAL_UART_WRITE8(UART_TRAN_HOLD_OFF, c);
}
int log_uart_readable(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
volatile u8 line_status;
line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
if (line_status & LSR_DR) {
return 1;
} else {
return 0;
}
}
int log_uart_writable(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
volatile u8 line_status;
line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
if (line_status & LSR_THRE) {
return 1;
} else {
return 0;
}
}
void log_uart_clear(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, (LOG_UART_RST_TX_FIFO|LOG_UART_RST_TX_FIFO));
pUartAdapter->TxCount = 0;
pUartAdapter->RxCount = 0;
}
void log_uart_clear_tx(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_TX_FIFO);
pUartAdapter->TxCount = 0;
}
void log_uart_clear_rx(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_RX_FIFO);
pUartAdapter->RxCount = 0;
}
void log_uart_break_set(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
u32 RegValue;
RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF);
RegValue |= LCR_BC;
HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue);
}
void log_uart_break_clear(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
u32 RegValue;
RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF);
RegValue &= ~LCR_BC;
HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue);
}
void log_uart_tx_comp_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
pUartAdapter->TxCompCallback = (void(*)(void*))handler;
pUartAdapter->TxCompCbPara = (void*)id;
}
void log_uart_rx_comp_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
pUartAdapter->RxCompCallback = (void(*)(void*))handler;
pUartAdapter->RxCompCbPara = (void*)id;
}
void log_uart_line_status_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
pUartAdapter->LineStatusCallback = (void(*)(void*, u8))handler;
pUartAdapter->LineStatusCbPara = (void*)id;
}
// Blocked(busy wait) receive, return received bytes count
int32_t log_uart_recv (log_uart_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartRecv(pUartAdapter, prxbuf, len, timeout_ms);
return (ret);
}
// Blocked(busy wait) send, return transmitted bytes count
int32_t log_uart_send (log_uart_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartSend(pUartAdapter, ptxbuf, len, timeout_ms);
return (ret);
}
// Interrupt mode(no wait) receive, return HAL function result
int32_t log_uart_recv_stream (log_uart_t *obj, char *prxbuf, uint32_t len)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len);
return (ret);
}
// Interrupt Mode(no wait) send, return HAL function result
int32_t log_uart_send_stream (log_uart_t *obj, char *ptxbuf, uint32_t len)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartIntSend(pUartAdapter, (u8*)ptxbuf, len);
return (ret);
}
// Interrupt mode(no wait) receive with timeout
// return the byte count received before timeout, or error(<0)
int32_t log_uart_recv_stream_timeout (log_uart_t *obj, char *prxbuf, uint32_t len,
uint32_t timeout_ms, void *force_cs)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
uint32_t TimeoutCount=0, StartCount;
int ret;
void (*task_yield)(void);
task_yield = NULL;
ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
task_yield = (void (*)(void))force_cs;
while (pUartAdapter->RxCount > 0) {
if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) {
HalLogUartAbortIntRecv(pUartAdapter);
break;
}
if (NULL != task_yield) {
task_yield();
}
}
return (len - pUartAdapter->RxCount);
} else {
return (-ret);
}
}
// Abort Interrupt Mode TX and return how many bytes data has been sent
int32_t log_uart_send_stream_abort (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
HalLogUartAbortIntSend(pUartAdapter);
ret = (u32)pUartAdapter->pTxBuf - (u32)pUartAdapter->pTxStartAddr;
return (ret);
}
// Abort Interrupt Mode RX and return how many bytes data has been received
int32_t log_uart_recv_stream_abort (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
HalLogUartAbortIntRecv(pUartAdapter);
ret = (u32)pUartAdapter->pRxBuf - (u32)pUartAdapter->pRxStartAddr;
return (ret);
}
void log_uart_disable (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
HalLogUartDisable(pUartAdapter);
}
void log_uart_enable (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
HalLogUartEnable(pUartAdapter);
}
// to read Line-Status register
// Bit 0: RX Data Ready
// Bit 1: Overrun Error
// Bit 2: Parity Error
// Bit 3: Framing Error
// Bit 4: Break Interrupt (received data input is held in 0 state for a longer than a full word tx time)
// Bit 5: TX FIFO empty (THR empty)
// Bit 6: TX FIFO empty (THR & TSR both empty)
// Bit 7: Receiver FIFO Error (parity error, framing error or break indication)
uint8_t log_uart_raed_lsr(log_uart_t *obj)
{
uint8_t LineStatus;
LineStatus = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
return LineStatus;
}
// to read Modem-Status register
// Bit 0: DCTS, The CTS line has changed its state
// Bit 1: DDSR, The DSR line has changed its state
// Bit 2: TERI, RI line has changed its state from low to high state
// Bit 3: DDCD, DCD line has changed its state
// Bit 4: Complement of the CTS input
// Bit 5: Complement of the DSR input
// Bit 6: Complement of the RI input
// Bit 7: Complement of the DCD input
uint8_t log_uart_raed_msr(log_uart_t *obj)
{
uint8_t RegValue;
RegValue = HAL_UART_READ8(UART_MODEM_STATUS_REG_OFF);
return RegValue;
}

View file

@ -0,0 +1,243 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "pinmap.h"
#if CONFIG_NFC_NORMAL
#include "nfc_api.h"
/**
* @brief The NFC tag write callback function wrapper
*
* @return None
*
*/
void nfc_tagwrite_callback(PNFC_ADAPTER pNFCAdp, uint32_t page, uint32_t wr_data)
{
nfctag_t *obj;
nfc_write_cb handler;
obj = pNFCAdp->nfc_obj;
handler = (nfc_write_cb)obj->nfc_wr_cb;
if (NULL != handler) {
handler(obj->wr_cb_arg, page, wr_data);
}
}
/**
* @brief The NFC tag read callback function wrapper
*
* @return None
*
*/
void nfc_event_callback(PNFC_ADAPTER pNFCAdp, uint32_t event)
{
nfctag_t *obj;
nfc_event_cb handler;
obj = pNFCAdp->nfc_obj;
handler = (nfc_event_cb)obj->nfc_ev_cb;
if (NULL != handler) {
if (obj->event_mask & event) {
handler(obj->ev_cb_arg, event);
}
}
}
/**
* @brief The NFC tag read callback function wrapper
*
* @return None
*
*/
void nfc_tagread_callback(PNFC_ADAPTER pNFCAdp, uint32_t page)
{
// notify upper layer when read tag page 0 only
if (0 == page) {
nfc_event_callback(pNFCAdp, NFC_EV_READ);
}
}
/**
* @brief The NFC cache read done callback function wrapper
*
* @return None
*
*/
void nfc_cache_read_callback(PNFC_ADAPTER pNFCAdp, uint32_t start_pg, uint32_t *pbuf)
{
nfctag_t *obj;
nfc_write_cb handler;
obj = pNFCAdp->nfc_obj;
handler = (nfc_write_cb)obj->nfc_cache_rd_cb;
if (NULL != handler) {
handler(obj->cache_read_cb_arg, start_pg, (uint32_t)pbuf);
}
}
/**
* @brief To initial NFC tag hardware and resource
*
* @return The result
*
*/
int nfc_init(nfctag_t *obj, uint32_t *pg_init_val)
{
_memset((void *)obj, 0, sizeof(nfctag_t));
HalNFCDmemInit(pg_init_val, NFCTAGLENGTH);
HalNFCInit(&(obj->NFCAdapter));
HalNFCFwDownload();
obj->NFCAdapter.nfc_obj = obj;
obj->pwr_status = NFC_PWR_RUNNING;
return NFC_OK;
}
/**
* @brief To free NFC tag hardware and resource
*
* @return The result
*
*/
int nfc_free(nfctag_t *obj)
{
HalNFCDeinit(&(obj->NFCAdapter));
return NFC_OK;
}
/**
* @brief To register the callback function for NFC read occurred
*
* @return None
*
*/
void nfc_read(nfctag_t *obj, nfc_read_cb handler, void *arg)
{
obj->nfc_rd_cb = (void *)handler;
obj->rd_cb_arg = arg;
}
/**
* @brief To register the callback function for NFC write occurred
*
* @return None
*
*/
void nfc_write(nfctag_t *obj, nfc_write_cb handler, void *arg)
{
obj->nfc_wr_cb = (void *)handler;
obj->wr_cb_arg = arg;
}
/**
* @brief To register the callback function for NFC events occurred
* and the event mask
*
* @return None
*
*/
void nfc_event(nfctag_t *obj, nfc_event_cb handler, void *arg, unsigned int event_mask)
{
obj->nfc_ev_cb = (void *)handler;
obj->ev_cb_arg = arg;
obj->event_mask = event_mask;
}
/**
* @brief To set a new power mode to the NFC device
*
* @return The result
*
*/
int nfc_power(nfctag_t *obj, int pwr_mode, int wake_event)
{
// TODO:
return NFC_OK;
}
/**
* @brief to update the NFC read cache. The data in the NFC read cache
* buffer will be transmitted out when NFC read occurred
*
* @return The result
*
*/
int nfc_cache_write(nfctag_t *obj, uint32_t *tbuf, unsigned int spage, unsigned int pg_num)
{
u8 remain_pg;
u8 pg_offset=0;
u8 i;
if ((spage+pg_num) > NFC_MAX_CACHE_PAGE_NUM) {
return NFC_ERROR;
}
remain_pg = pg_num;
while (remain_pg > 0) {
if (remain_pg >= 4) {
A2NWriteCatch (&obj->NFCAdapter, (spage+pg_offset), 4, (u32*)(&tbuf[pg_offset]));
remain_pg -= 4;
pg_offset += 4;
}
else {
for(i=0;i<remain_pg;i++) {
A2NWriteCatch (&obj->NFCAdapter, (spage+pg_offset), 1, (u32*)(&tbuf[pg_offset]));
pg_offset++;
}
remain_pg = 0;
}
}
return NFC_OK;
}
/**
* @brief To get current NFC status
*
* @return The result
*
*/
int nfc_cache_raed(nfctag_t *obj, nfc_cache_read_cb handler,
void *arg, unsigned int start_pg)
{
if (start_pg > NFC_MAX_CACHE_PAGE_NUM) {
return NFC_ERROR;
}
obj->nfc_cache_rd_cb = (void *)handler;
obj->cache_read_cb_arg = arg;
A2NReadCatch(&(obj->NFCAdapter), (u8)start_pg);
return NFC_OK;
}
/**
* @brief to read back the NFC read cache.
*
* @return The result
*
*/
int nfc_status(nfctag_t *obj)
{
// TODO:
return (obj->pwr_status);
}
#endif

View file

@ -0,0 +1,207 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "platform_autoconf.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_GPIO_EN
struct gpio_irq_s {
PinName pin;
uint32_t event;
HAL_GPIO_PIN hal_pin;
uint8_t hal_port_num;
uint8_t hal_pin_num;
};
typedef struct gpio_irq_s gpio_irq_t;
struct gpio_s {
PinName pin;
PinMode mode;
PinDirection direction;
HAL_GPIO_PIN hal_pin;
uint8_t hal_port_num;
uint8_t hal_pin_num;
};
typedef struct gpio_s gpio_t;
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
uint8_t *pin_def;
};
#endif // end of "#ifdef CONFIG_GPIO_EN"
#ifdef CONFIG_UART_EN
struct serial_s {
HAL_RUART_OP hal_uart_op;
HAL_RUART_ADAPTER hal_uart_adp;
#ifdef CONFIG_GDMA_EN
UART_DMA_CONFIG uart_gdma_cfg;
HAL_GDMA_ADAPTER uart_gdma_adp_tx;
HAL_GDMA_ADAPTER uart_gdma_adp_rx;
UART_DMA_MULTIBLK gdma_multiblk_list_tx;
UART_DMA_MULTIBLK gdma_multiblk_list_rx;
#endif
uint32_t tx_len;
uint32_t rx_len;
};
#endif // end of "#ifdef CONFIG_UART_EN"
struct log_uart_s {
HAL_LOG_UART_ADAPTER log_hal_uart;
};
#ifdef CONFIG_SPI_COM_EN
#endif
#ifdef CONFIG_PWM_EN
struct pwmout_s {
uint8_t pwm_idx;
uint8_t pin_sel;
uint32_t period;
uint32_t pulse;
HAL_PWM_ADAPTER pwm_hal_adp;
};
#endif
#ifdef CONFIG_I2C_EN
struct i2c_s {
SAL_I2C_MNGT_ADPT SalI2CMngtAdpt;
SAL_I2C_HND_PRIV SalI2CHndPriv;
HAL_I2C_INIT_DAT HalI2CInitData;
HAL_I2C_OP HalI2COp;
IRQ_HANDLE I2CIrqHandleDat;
HAL_GDMA_ADAPTER HalI2CTxGdmaAdpt;
HAL_GDMA_ADAPTER HalI2CRxGdmaAdpt;
HAL_GDMA_OP HalI2CGdmaOp;
IRQ_HANDLE I2CTxGdmaIrqHandleDat;
IRQ_HANDLE I2CRxGdmaIrqHandleDat;
SAL_I2C_USER_CB SalI2CUserCB;
SAL_I2C_USERCB_ADPT SalI2CUserCBAdpt[SAL_USER_CB_NUM];
SAL_I2C_DMA_USER_DEF SalI2CDmaUserDef;
};
#endif
struct flash_s
{
SPIC_INIT_PARA SpicInitPara;
u32 Length;
};
#ifdef CONFIG_ADC_EN
struct analogin_s {
SAL_ADC_MNGT_ADPT SalADCMngtAdpt;
SAL_ADC_HND_PRIV SalADCHndPriv;
HAL_ADC_INIT_DAT HalADCInitData;
HAL_ADC_OP HalADCOp;
IRQ_HANDLE ADCIrqHandleDat;
HAL_GDMA_ADAPTER HalADCGdmaAdpt;
HAL_GDMA_OP HalADCGdmaOp;
IRQ_HANDLE ADCGdmaIrqHandleDat;
SAL_ADC_USER_CB SalADCUserCB;
SAL_ADC_USERCB_ADPT SalADCUserCBAdpt[SAL_ADC_USER_CB_NUM];
};
#endif
#if 0
struct i2c_s {
I2C_Type *i2c;
};
struct spi_s {
SPI_Type *spi;
};
#endif
#ifdef CONFIG_NFC_EN
struct nfctag_s {
NFC_ADAPTER NFCAdapter;
void *nfc_rd_cb; // read callback function
void *rd_cb_arg;
void *nfc_wr_cb; // write callback function
void *wr_cb_arg;
void *nfc_ev_cb; // event callback function
void *ev_cb_arg;
void *nfc_cache_rd_cb; // cache read callback function
void *cache_read_cb_arg;
unsigned int event_mask;
int pwr_status;
};
#endif
#ifdef CONFIG_TIMER_EN
struct gtimer_s {
TIMER_ADAPTER hal_gtimer_adp;
void *handler;
u32 hid;
u8 timer_id;
u8 is_periodcal;
};
#endif
#ifdef CONFIG_I2S_EN
struct i2s_s {
HAL_I2S_ADAPTER I2SAdapter;
HAL_I2S_INIT_DAT InitDat;
u8 sampling_rate;
u8 channel_num;
u8 word_length;
u8 direction;
};
#endif
#ifdef CONFIG_DAC_EN
/** \file objects.h
* \brief A Documented file.
*
* A documented file.
*/
/** \struct dac_s objects.h "rtl8195a/objects.h"
* \brief This is a dac_s structure.
*
* For analogout APIs, a pointer to dac_s is used as an input paras.
* A DAC initial data structure is the major element of dac_s.
*/
struct dac_s {
HAL_DAC_INIT_DAT DACpara;
};
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,34 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
//#include "mbed_assert.h"
#include "objects.h"
#include "pinmap.h"
//#include "error.h"
/**
* Configure pin enable and function
*/
void pin_function(PinName pin, int function)
{
// MBED_ASSERT(pin != (PinName)NC);
//1 Our HAL API cannot support to configure the pin function by this way
/* the pin function (pin mux) is depends on each IP On/Off and priority, so we cannot
set the pin function directly */
}
/**
* Configure pin pull-up/pull-down
*/
void pin_mode(PinName pin, PinMode mode)
{
// MBED_ASSERT(pin != (PinName)NC);
HAL_GPIO_PullCtrl((u32)pin, (u32)mode);
}

View file

@ -0,0 +1,73 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "basic_types.h"
#include "diag.h"
#include "pinmap.h"
//#include "error.h"
__weak void pinmap_pinout(PinName pin, const PinMap *map) {
#if 0
if (pin == NC)
return;
while (map->pin != NC) {
if (map->pin == pin) {
pin_function(pin, map->function);
pin_mode(pin, PullNone);
return;
}
map++;
}
DBG_GPIO_ERR("%s: could not pinout\n", __FUNCTION__);
#endif
}
__weak uint32_t pinmap_merge(uint32_t a, uint32_t b) {
// both are the same (inc both NC)
if (a == b)
return a;
// one (or both) is not connected
if (a == (uint32_t)NC)
return b;
if (b == (uint32_t)NC)
return a;
// mis-match error case
DBG_GPIO_ERR("%s: pinmap mis-match\n", __FUNCTION__);
return (uint32_t)NC;
}
__weak uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) {
while (map->pin != NC) {
if (map->pin == pin)
return map->peripheral;
map++;
}
return (uint32_t)NC;
}
__weak uint32_t pinmap_peripheral(PinName pin, const PinMap* map) {
uint32_t peripheral = (uint32_t)NC;
if (pin == (PinName)NC)
return (uint32_t)NC;
peripheral = pinmap_find_peripheral(pin, map);
if ((uint32_t)NC == peripheral) // no mapping available
DBG_GPIO_ERR("%s: pinmap not found for peripheral\n", __FUNCTION__);
return peripheral;
}

View file

@ -0,0 +1,212 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "port_api.h"
#include "pinmap.h"
#include "gpio_api.h"
#include "PinNames.h"
//#include "mbed_error.h"
#if CONFIG_GPIO_EN
#if DEVICE_PORTIN || DEVICE_PORTOUT
#define GPIO_PORT_NUM 3
#define GPIO_PORT_WIDTH 32
#define GPIO_PORT_WIDTH_MAX 32
const u8 Default_Port_PinDef[GPIO_PORT_NUM][GPIO_PORT_WIDTH+1] = {
// Port 0 has these pin:
{PA_0, PA_1, PB_3, PB_4,
PB_6, PB_7, PC_1, PC_3,
PC_4, PC_5, PC_6, PC_7,
PC_8, PC_9, PD_1, PD_3,
PD_4, PD_5, PD_6, PD_7,
PD_9, PE_1, PE_2, PE_3,
PE_5, PE_6, PE_7, PE_8,
PG_3, PH_1, PH_3, PH_5,
0xFF},
// Port 1
{PA_2, PA_3, PA_4, PA_5,
PA_6, PA_7, PB_0, PB_1,
PB_2, PB_5, PC_0, PC_2,
PD_0, PD_2, PD_8, PE_0,
PE_4, PE_9, PE_A, PF_0,
PF_1, PF_2, PF_3, PF_4,
PF_5, PG_0, PG_1, PG_2,
PG_4, PG_5, PG_6, PG_7,
0xFF},
// Port 2
{PH_0, PH_2, PH_4, 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,
0xFF}
};
extern const u8 GPIO_SWPORT_DR_TBL[];
extern const u8 GPIO_EXT_PORT_TBL[];
extern VOID HAL_GPIO_Init(HAL_GPIO_PIN *GPIO_Pin);
extern u32 HAL_GPIO_GetPinName(u32 chip_pin);
// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
// low nibble = pin number
PinName port_pin(PortName port, int pin_n) {
return (PinName)(pin_n + (port << 4));
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
u32 i;
if (port >= GPIO_PORT_NUM) {
DBG_GPIO_ERR("port_init: Invalid port num(%d), max port num is %d\r\n", \
port, (GPIO_PORT_NUM-1));
}
// Fill PORT object structure for future use
obj->port = port;
obj->mask = mask;
obj->direction = dir;
if (obj->pin_def == NULL) {
DBG_GPIO_ERR("Port Define Table isn't assigned\n");
obj->pin_def = (uint8_t*)&Default_Port_PinDef[port][0];
}
i=0;
while (obj->pin_def[i] != 0xff) {
i++;
if (i == GPIO_PORT_WIDTH_MAX) {
break;
}
}
obj->mask &= ((1<<i) - 1);
port_dir(obj, dir);
}
void port_dir(port_t *obj, PinDirection dir)
{
uint32_t i;
HAL_GPIO_PIN GPIO_Pin;
obj->direction = dir;
for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins
if (obj->pin_def[i] == 0xff) {
// end of table
break;
}
if (obj->mask & (1 << i)) { // If the pin is used
GPIO_Pin.pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name
if (dir == PIN_OUTPUT) {
GPIO_Pin.pin_mode = DOUT_PUSH_PULL;
} else { // PIN_INPUT
GPIO_Pin.pin_mode = DIN_PULL_NONE;
}
HAL_GPIO_Init(&GPIO_Pin);
}
}
}
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins
if (obj->pin_def[i] == 0xff) {
// end of table
break;
}
if (obj->mask & (1 << i)) { // If the pin is used
pin_mode(obj->pin_def[i], mode);
}
}
}
void port_write(port_t *obj, int value)
{
uint32_t i;
uint32_t pin_name;
uint8_t port_num;
uint8_t pin_num;
uint32_t hal_port[3];
uint8_t port_changed[3];
for (i=0;i<3;i++) {
hal_port[i] = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[i]);
port_changed[i] = 0;
}
for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins
if (obj->pin_def[i] == 0xff) {
// end of table
break;
}
if (obj->mask & (1 << i)) { // If the pin is used
pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name
port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name);
pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name);
hal_port[port_num] &= ~(1 << pin_num);
hal_port[port_num] |= (((value>>i) & 0x01)<< pin_num);
port_changed[port_num] = 1;
}
}
for (i=0;i<3;i++) {
if (port_changed[i]) {
HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[i], hal_port[i]);
}
}
}
int port_read(port_t *obj)
{
int value=0;
u32 i;
uint32_t pin_name;
uint8_t port_num;
uint8_t pin_num;
uint32_t hal_port[3];
for (i=0;i<3;i++) {
hal_port[i] = HAL_READ32(GPIO_REG_BASE, GPIO_EXT_PORT_TBL[i]);
}
for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins
if (obj->pin_def[i] == 0xff) {
// end of table
break;
}
if (obj->mask & (1 << i)) { // If the pin is used
pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name
port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name);
pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name);
if (hal_port[port_num] & (1<<pin_num)) {
value |= (1<<i);
}
}
}
return value;
}
#endif
#endif

View file

@ -0,0 +1,100 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
*******************************************************************************
* bug fixing: pvvx
*/
#include "device.h"
#include "objects.h"
#include "pinmap.h"
//#include <rtl_lib.h>
#if DEVICE_PWMOUT
#ifdef CONFIG_PWM_EN
#include "pwmout_api.h"
#include "objects.h"
extern u32 gTimerRecord;
const PinMap PinMap_PWM[] = {
{PB_4, RTL_PIN_PERI(PWM0, 0, S0), RTL_PIN_FUNC(PWM0, S0)},
{PB_5, RTL_PIN_PERI(PWM1, 1, S0), RTL_PIN_FUNC(PWM1, S0)},
{PB_6, RTL_PIN_PERI(PWM2, 2, S0), RTL_PIN_FUNC(PWM2, S0)},
{PB_7, RTL_PIN_PERI(PWM3, 3, S0), RTL_PIN_FUNC(PWM3, S0)},
{PC_0, RTL_PIN_PERI(PWM0, 0, S1), RTL_PIN_FUNC(PWM0, S1)},
{PC_1, RTL_PIN_PERI(PWM1, 1, S1), RTL_PIN_FUNC(PWM1, S1)},
{PC_2, RTL_PIN_PERI(PWM2, 2, S1), RTL_PIN_FUNC(PWM2, S1)},
{PC_3, RTL_PIN_PERI(PWM3, 3, S1), RTL_PIN_FUNC(PWM3, S1)},
{PD_3, RTL_PIN_PERI(PWM0, 0, S2), RTL_PIN_FUNC(PWM0, S2)},
{PD_4, RTL_PIN_PERI(PWM1, 1, S2), RTL_PIN_FUNC(PWM1, S2)},
{PD_5, RTL_PIN_PERI(PWM2, 2, S2), RTL_PIN_FUNC(PWM2, S2)},
{PD_6, RTL_PIN_PERI(PWM3, 3, S2), RTL_PIN_FUNC(PWM3, S2)},
{PE_0, RTL_PIN_PERI(PWM0, 0, S3), RTL_PIN_FUNC(PWM0, S3)},
{PE_1, RTL_PIN_PERI(PWM1, 1, S3), RTL_PIN_FUNC(PWM1, S3)},
{PE_2, RTL_PIN_PERI(PWM2, 2, S3), RTL_PIN_FUNC(PWM2, S3)},
{PE_3, RTL_PIN_PERI(PWM3, 3, S3), RTL_PIN_FUNC(PWM3, S3)},
{NC, NC, 0}
};
int pwmout_init(pwmout_t* obj, PinName pin)
{
uint32_t peripheral;
u32 pwm_idx;
u32 pin_sel;
DBG_PWM_INFO("%s: Init PWM for pin(0x%x)\n", __FUNCTION__, pin);
// Get the peripheral name from the pin and assign it to the object
peripheral = pinmap_peripheral(pin, PinMap_PWM);
if (unlikely(peripheral == NC)) {
DBG_PWM_ERR("%s: Cannot find matched pwm for this pin(0x%x)\n", __FUNCTION__, pin);
return -1;
}
pwm_idx = RTL_GET_PERI_IDX(peripheral);
pin_sel = RTL_GET_PERI_SEL(peripheral);
obj->pwm_idx = pwm_idx;
obj->pin_sel = pin_sel;
obj->period = 0;
obj->pulse = 0;
rtl_memset((void *)&obj->pwm_hal_adp, 0, sizeof(HAL_PWM_ADAPTER));
if (HAL_OK != HAL_Pwm_Init(&obj->pwm_hal_adp, pwm_idx, pin_sel)) {
DBG_PWM_ERR("pwmout_init Err!\n");
return -1;
}
// pwmout_period_us(obj, 20000); // 20 ms per default
// HAL_Pwm_Enable(&obj->pwm_hal_adp);
return 0;
}
void pwmout_free(pwmout_t* obj)
{
HAL_Pwm_Disable(&obj->pwm_hal_adp);
gTimerRecord &= ~(1 << obj->pwm_hal_adp.gtimer_id);
}
void pwmout_period_us(pwmout_t* obj, uint32_t us)
{
obj->period = us;
HAL_Pwm_SetDuty(&obj->pwm_hal_adp, us, obj->pulse);
}
void pwmout_pulsewidth_us(pwmout_t* obj, uint32_t us)
{
obj->pulse = us;
if(us > obj->period) obj->period = us;
HAL_Pwm_SetDuty(&obj->pwm_hal_adp, obj->period, us);
}
#endif // #ifdef CONFIG_PWM_EN
#endif

View file

@ -0,0 +1,120 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2015, Realtek Semiconductor Corp.
* All rights reserved.
*
* 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"
#if DEVICE_RTC
#include <time.h>
#include "timer_api.h" // software-RTC: use a g-timer for the tick of the RTC
#define SW_RTC_TIMER_ID TIMER4
static gtimer_t sw_rtc;
static struct tm rtc_timeinfo;
static int sw_rtc_en=0;
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;
}
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 + 1900)) {
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
}
}
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);
sw_rtc_en = 1;
}
void rtc_free(void)
{
sw_rtc_en = 0;
gtimer_stop(&sw_rtc);
gtimer_deinit(&sw_rtc);
}
int rtc_isenabled(void)
{
return(sw_rtc_en);
}
time_t rtc_read(void)
{
time_t t;
// Convert to timestamp
t = mktime(&rtc_timeinfo);
return t;
}
void rtc_write(time_t t)
{
// Convert the time in to a tm
struct tm *timeinfo = localtime(&t);
if (timeinfo == NULL) {
// Error
return;
}
gtimer_stop(&sw_rtc);
// Set the RTC
rtc_timeinfo.tm_sec = timeinfo->tm_sec;
rtc_timeinfo.tm_min = timeinfo->tm_min;
rtc_timeinfo.tm_hour = timeinfo->tm_hour;
rtc_timeinfo.tm_mday = timeinfo->tm_mday;
rtc_timeinfo.tm_wday = timeinfo->tm_wday;
rtc_timeinfo.tm_yday = timeinfo->tm_yday;
rtc_timeinfo.tm_mon = timeinfo->tm_mon;
rtc_timeinfo.tm_year = timeinfo->tm_year;
gtimer_start(&sw_rtc);
}
#endif // endof "#if DEVICE_RTC"

View file

@ -0,0 +1,800 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
//#include "mbed_assert.h"
#include "serial_api.h"
#include "serial_ex_api.h"
#if CONFIG_UART_EN
//#include "cmsis.h"
#include "pinmap.h"
#include <string.h>
static const PinMap PinMap_UART_TX[] = {
{PC_3, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)},
{PE_0, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)},
{PA_7, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)}, // None RTL8710AF
{PD_3, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)}, // None RTL8710AF, RTL8711AM
{PE_4, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)},
{PB_5, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)}, // None RTL8710AF, RTL8711AM
{PA_4, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)}, // None RTL8711AM
{PC_9, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)}, // None RTL8710AF, RTL8711AM
{PD_7, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)}, // None RTL8710AF, RTL8711AM
{NC, NC, 0}
};
static const PinMap PinMap_UART_RX[] = {
{PC_0, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)}, // No Interrupt Source?
{PE_3, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)},
{PA_6, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)}, // None RTL8710AF, // No Interrupt Source?
{PD_0, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)}, // None RTL8710AF, RTL8711AM
{PE_7, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)}, // None RTL8710AF, RTL8711AM
{PB_4, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)}, // None RTL8710AF, RTL8711AM
{PA_0, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)}, // None RTL8711AM
{PC_6, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)}, // None RTL8710AF, RTL8711AM
{PD_4, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)}, // None RTL8710AF, RTL8711AM
{NC, NC, 0}
};
#define UART_NUM (3)
#define SERIAL_TX_IRQ_EN 0x01
#define SERIAL_RX_IRQ_EN 0x02
#define SERIAL_TX_DMA_EN 0x01
#define SERIAL_RX_DMA_EN 0x02
static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0}; // , 0
static uart_irq_handler irq_handler[UART_NUM];
static uint32_t serial_irq_en[UART_NUM] = {0, 0, 0}; // , 0
#ifdef CONFIG_GDMA_EN
static uint32_t serial_dma_en[UART_NUM] = {0, 0, 0}; // , 0
static HAL_GDMA_OP UartGdmaOp;
#endif
#ifdef CONFIG_MBED_ENABLED
int stdio_uart_inited = 0;
serial_t stdio_uart;
#endif
static void SerialTxDoneCallBack(VOID *pAdapter);
static void SerialRxDoneCallBack(VOID *pAdapter);
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
uint32_t uart_tx, uart_rx;
uint32_t uart_sel;
uint8_t uart_idx;
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter;
#ifdef CONFIG_GDMA_EN
PUART_DMA_CONFIG pHalRuartDmaCfg;
PHAL_GDMA_OP pHalGdmaOp=&UartGdmaOp;
#endif
// Determine the UART to use (UART0, UART1, or UART3)
uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
uart_sel = pinmap_merge(uart_tx, uart_rx);
uart_idx = RTL_GET_PERI_IDX(uart_sel);
if (unlikely(uart_idx == (uint8_t)NC)) {
DBG_UART_ERR("%s: Cannot find matched UART\n", __FUNCTION__);
return;
}
pHalRuartOp = &(obj->hal_uart_op);
pHalRuartAdapter = &(obj->hal_uart_adp);
if ((NULL == pHalRuartOp) || (NULL == pHalRuartAdapter)) {
DBG_UART_ERR("%s: Allocate Adapter Failed\n", __FUNCTION__);
return;
}
HalRuartOpInit((VOID*)pHalRuartOp);
#ifdef CONFIG_GDMA_EN
HalGdmaOpInit((VOID*)pHalGdmaOp);
pHalRuartDmaCfg = &obj->uart_gdma_cfg;
pHalRuartDmaCfg->pHalGdmaOp = pHalGdmaOp;
pHalRuartDmaCfg->pTxHalGdmaAdapter = &obj->uart_gdma_adp_tx;
pHalRuartDmaCfg->pRxHalGdmaAdapter = &obj->uart_gdma_adp_rx;
pHalRuartDmaCfg->pTxDmaBlkList = &obj->gdma_multiblk_list_tx;
pHalRuartDmaCfg->pRxDmaBlkList = &obj->gdma_multiblk_list_rx;
_memset((void*)(pHalRuartDmaCfg->pTxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER));
_memset((void*)(pHalRuartDmaCfg->pRxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER));
_memset((void*)(pHalRuartDmaCfg->pTxDmaBlkList), 0, sizeof(UART_DMA_MULTIBLK));
_memset((void*)(pHalRuartDmaCfg->pRxDmaBlkList), 0, sizeof(UART_DMA_MULTIBLK));
#endif
pHalRuartOp->HalRuartAdapterLoadDef(pHalRuartAdapter, uart_idx);
pHalRuartAdapter->PinmuxSelect = RTL_GET_PERI_SEL(uart_sel);
pHalRuartAdapter->BaudRate = 9600;
pHalRuartAdapter->IrqHandle.Priority = 6;
// Configure the UART pins
// TODO:
// pinmap_pinout(tx, PinMap_UART_TX);
// pinmap_pinout(rx, PinMap_UART_RX);
// pin_mode(tx, PullUp);
// pin_mode(rx, PullUp);
if (HalRuartInit(pHalRuartAdapter) != HAL_OK) {
DBG_UART_ERR("serial_init Err!\n");
return;
}
pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
#ifdef CONFIG_MBED_ENABLED
// For stdio management
if (uart_idx == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
#endif
}
void serial_free(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
#ifdef CONFIG_GDMA_EN
u8 uart_idx;
PUART_DMA_CONFIG pHalRuartDmaCfg;
#endif
pHalRuartAdapter = &(obj->hal_uart_adp);
HalRuartDeInit(pHalRuartAdapter);
#ifdef CONFIG_GDMA_EN
uart_idx = pHalRuartAdapter->UartIndex;
pHalRuartDmaCfg = &obj->uart_gdma_cfg;
if (serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN) {
HalRuartRxGdmaDeInit(pHalRuartDmaCfg);
serial_dma_en[uart_idx] &= ~SERIAL_RX_DMA_EN;
}
if (serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN) {
HalRuartTxGdmaDeInit(pHalRuartDmaCfg);
serial_dma_en[uart_idx] &= ~SERIAL_TX_DMA_EN;
}
#endif
}
void serial_baud(serial_t *obj, int baudrate) {
PHAL_RUART_ADAPTER pHalRuartAdapter;
//PHAL_RUART_OP pHalRuartOp;
pHalRuartAdapter = &(obj->hal_uart_adp);
//pHalRuartOp = &(obj->hal_uart_op);
pHalRuartAdapter->BaudRate = baudrate;
// HalRuartInit(pHalRuartAdapter);
HalRuartSetBaudRate((VOID*)pHalRuartAdapter);
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
//PHAL_RUART_OP pHalRuartOp;
pHalRuartAdapter = &(obj->hal_uart_adp);
//pHalRuartOp = &(obj->hal_uart_op);
if (data_bits == 8) {
pHalRuartAdapter->WordLen = RUART_WLS_8BITS;
} else {
pHalRuartAdapter->WordLen = RUART_WLS_7BITS;
}
switch (parity) {
case ParityOdd:
case ParityForced0:
pHalRuartAdapter->Parity = RUART_PARITY_ENABLE;
pHalRuartAdapter->ParityType = RUART_ODD_PARITY;
break;
case ParityEven:
case ParityForced1:
pHalRuartAdapter->Parity = RUART_PARITY_ENABLE;
pHalRuartAdapter->ParityType = RUART_EVEN_PARITY;
break;
default: // ParityNone
pHalRuartAdapter->Parity = RUART_PARITY_DISABLE;
break;
}
if (stop_bits == 2) {
pHalRuartAdapter->StopBit = RUART_STOP_BIT_2;
} else {
pHalRuartAdapter->StopBit = RUART_STOP_BIT_1;
}
HalRuartInit(pHalRuartAdapter);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
static void SerialTxDoneCallBack(VOID *pAdapter)
{
PHAL_RUART_ADAPTER pHalRuartAdapter = pAdapter;
u8 uart_idx = pHalRuartAdapter->UartIndex;
// Mask UART TX FIFO empty
pHalRuartAdapter->Interrupts &= ~RUART_IER_ETBEI;
HalRuartSetIMRRtl8195a (pHalRuartAdapter);
if (irq_handler[uart_idx] != NULL) {
irq_handler[uart_idx](serial_irq_ids[uart_idx], TxIrq);
}
}
static void SerialRxDoneCallBack(VOID *pAdapter)
{
PHAL_RUART_ADAPTER pHalRuartAdapter = pAdapter;
u8 uart_idx = pHalRuartAdapter->UartIndex;
if (irq_handler[uart_idx] != NULL) {
irq_handler[uart_idx](serial_irq_ids[uart_idx], RxIrq);
}
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
// PHAL_RUART_OP pHalRuartOp;
u8 uart_idx;
pHalRuartAdapter = &(obj->hal_uart_adp);
// pHalRuartOp = &(obj->hal_uart_op);
uart_idx = pHalRuartAdapter->UartIndex;
irq_handler[uart_idx] = handler;
serial_irq_ids[uart_idx] = id;
pHalRuartAdapter->TxTDCallback = SerialTxDoneCallBack;
pHalRuartAdapter->TxTDCbPara = (void*)pHalRuartAdapter;
pHalRuartAdapter->RxDRCallback = SerialRxDoneCallBack;
pHalRuartAdapter->RxDRCbPara = (void*)pHalRuartAdapter;
// pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
// pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
PHAL_RUART_OP pHalRuartOp;
u8 uart_idx;
pHalRuartAdapter = &(obj->hal_uart_adp);
pHalRuartOp = &(obj->hal_uart_op);
uart_idx = pHalRuartAdapter->UartIndex;
if (enable) {
if (irq == RxIrq) {
pHalRuartAdapter->Interrupts |= RUART_IER_ERBI | RUART_IER_ELSI;
serial_irq_en[uart_idx] |= SERIAL_RX_IRQ_EN;
HalRuartSetIMRRtl8195a (pHalRuartAdapter);
}
else {
serial_irq_en[uart_idx] |= SERIAL_TX_IRQ_EN;
}
pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
}
else { // disable
if (irq == RxIrq) {
pHalRuartAdapter->Interrupts &= ~(RUART_IER_ERBI | RUART_IER_ELSI);
serial_irq_en[uart_idx] &= ~SERIAL_RX_IRQ_EN;
}
else {
pHalRuartAdapter->Interrupts &= ~RUART_IER_ETBEI;
serial_irq_en[uart_idx] &= ~SERIAL_TX_IRQ_EN;
}
HalRuartSetIMRRtl8195a (pHalRuartAdapter);
if (pHalRuartAdapter->Interrupts == 0) {
InterruptUnRegister(&pHalRuartAdapter->IrqHandle);
InterruptDis(&pHalRuartAdapter->IrqHandle);
}
}
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
while (!serial_readable(obj));
return (int)((HAL_RUART_READ32(uart_idx, RUART_REV_BUF_REG_OFF)) & 0xFF);
}
void serial_putc(serial_t *obj, int c)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
while (!serial_writable(obj));
HAL_RUART_WRITE32(uart_idx, RUART_TRAN_HOLD_REG_OFF, (c & 0xFF));
if (serial_irq_en[uart_idx] & SERIAL_TX_IRQ_EN) {
// UnMask TX FIFO empty IRQ
pHalRuartAdapter->Interrupts |= RUART_IER_ETBEI;
HalRuartSetIMRRtl8195a (pHalRuartAdapter);
}
}
int serial_readable(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
if ((HAL_RUART_READ32(uart_idx, RUART_LINE_STATUS_REG_OFF)) & RUART_LINE_STATUS_REG_DR) {
return 1;
}
else {
return 0;
}
}
int serial_writable(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
if (HAL_RUART_READ32(uart_idx, RUART_LINE_STATUS_REG_OFF) &
(RUART_LINE_STATUS_REG_THRE)) {
return 1;
}
else {
return 0;
}
}
void serial_clear(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
HalRuartResetTRxFifo((VOID *)pHalRuartAdapter);
}
void serial_clear_tx(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
HalRuartResetTxFifo((VOID *)pHalRuartAdapter);
}
void serial_clear_rx(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
HalRuartResetRxFifo((VOID *)pHalRuartAdapter);
}
void serial_pinout_tx(PinName tx)
{
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
u32 RegValue;
RegValue = HAL_RUART_READ32(uart_idx, RUART_LINE_CTL_REG_OFF);
RegValue |= BIT_UART_LCR_BREAK_CTRL;
HAL_RUART_WRITE32(uart_idx, RUART_LINE_CTL_REG_OFF, RegValue);
}
void serial_break_clear(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
u32 RegValue;
RegValue = HAL_RUART_READ32(uart_idx, RUART_LINE_CTL_REG_OFF);
RegValue &= ~(BIT_UART_LCR_BREAK_CTRL);
HAL_RUART_WRITE32(uart_idx, RUART_LINE_CTL_REG_OFF, RegValue);
}
void serial_send_comp_handler(serial_t *obj, void *handler, uint32_t id)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
pHalRuartAdapter->TxCompCallback = (void(*)(void*))handler;
pHalRuartAdapter->TxCompCbPara = (void*)id;
}
void serial_recv_comp_handler(serial_t *obj, void *handler, uint32_t id)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
pHalRuartAdapter->RxCompCallback = (void(*)(void*))handler;
pHalRuartAdapter->RxCompCbPara = (void*)id;
}
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
// Our UART cannot specify the RTS/CTS pin seprately, so the ignore the rxflow, txflow pin
// We just use the hardware auto flow control, so cannot do flow-control single direction only
pHalRuartAdapter = &(obj->hal_uart_adp);
// RTS low active
// RTS_pin = autoflow_en ? (~rts | (RX_FIFO_Level_Trigger)) : ~rts
switch(type) {
case FlowControlRTSCTS:
pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE;
pHalRuartAdapter->RTSCtrl = 1;
break;
case FlowControlRTS: // to indicate peer that it's ready for RX
// It seems cannot only enable RTS
pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE;
pHalRuartAdapter->RTSCtrl = 1;
break;
case FlowControlCTS: // to check is the peer ready for RX: if can start TX ?
// need to check CTS before TX
pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE;
pHalRuartAdapter->RTSCtrl = 1;
break;
case FlowControlNone:
default:
pHalRuartAdapter->FlowControl = AUTOFLOW_DISABLE;
pHalRuartAdapter->RTSCtrl = 1; // RTS pin allways Low, peer can send data
break;
}
HalRuartFlowCtrl((VOID *)pHalRuartAdapter);
}
// Blocked(busy wait) receive, return received bytes count
int32_t serial_recv_blocked (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
obj->rx_len = len;
HalRuartEnterCritical(pHalRuartAdapter);
ret = pHalRuartOp->HalRuartRecv(pHalRuartAdapter, (u8*)prxbuf, len, timeout_ms);
HalRuartExitCritical(pHalRuartAdapter);
return (ret);
}
// Blocked(busy wait) send, return transmitted bytes count
int32_t serial_send_blocked (serial_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
obj->tx_len = len;
ret = pHalRuartOp->HalRuartSend(pHalRuartAdapter, (u8*)ptxbuf, len, timeout_ms);
return (ret);
}
int32_t serial_recv_stream (serial_t *obj, char *prxbuf, uint32_t len)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
obj->rx_len = len;
ret = pHalRuartOp->HalRuartIntRecv(pHalRuartAdapter, (u8*)prxbuf, len);
return (ret);
}
int32_t serial_send_stream (serial_t *obj, char *ptxbuf, uint32_t len)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
obj->tx_len = len;
HalRuartEnterCritical(pHalRuartAdapter);
ret = pHalRuartOp->HalRuartIntSend(pHalRuartAdapter, (u8*)ptxbuf, len);
HalRuartExitCritical(pHalRuartAdapter);
return (ret);
}
#ifdef CONFIG_GDMA_EN
int32_t serial_recv_stream_dma (serial_t *obj, char *prxbuf, uint32_t len)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
int32_t ret;
pHalRuartOp = &(obj->hal_uart_op);
if ((serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN)==0) {
PUART_DMA_CONFIG pHalRuartDmaCfg;
pHalRuartDmaCfg = &obj->uart_gdma_cfg;
if (HAL_OK == HalRuartRxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) {
serial_dma_en[uart_idx] |= SERIAL_RX_DMA_EN;
}
else {
return HAL_BUSY;
}
}
obj->rx_len = len;
HalRuartEnterCritical(pHalRuartAdapter);
ret = HalRuartDmaRecv(pHalRuartAdapter, (u8*)prxbuf, len);
HalRuartExitCritical(pHalRuartAdapter);
return (ret);
}
int32_t serial_send_stream_dma (serial_t *obj, char *ptxbuf, uint32_t len)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
int32_t ret;
pHalRuartOp = &(obj->hal_uart_op);
if ((serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN)==0) {
PUART_DMA_CONFIG pHalRuartDmaCfg;
pHalRuartDmaCfg = &obj->uart_gdma_cfg;
if (HAL_OK == HalRuartTxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) {
serial_dma_en[uart_idx] |= SERIAL_TX_DMA_EN;
}
else {
return HAL_BUSY;
}
}
obj->tx_len = len;
HalRuartEnterCritical(pHalRuartAdapter);
ret = HalRuartDmaSend(pHalRuartAdapter, (u8*)ptxbuf, len);
HalRuartExitCritical(pHalRuartAdapter);
return (ret);
}
int32_t serial_recv_stream_dma_timeout (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms, void *force_cs)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
u8 uart_idx = pHalRuartAdapter->UartIndex;
uint32_t TimeoutCount=0, StartCount;
int ret;
void (*task_yield)(void);
pHalRuartOp = &(obj->hal_uart_op);
if ((serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN)==0) {
PUART_DMA_CONFIG pHalRuartDmaCfg;
pHalRuartDmaCfg = &obj->uart_gdma_cfg;
if (HAL_OK == HalRuartRxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) {
serial_dma_en[uart_idx] |= SERIAL_RX_DMA_EN;
}
else {
return HAL_BUSY;
}
}
HalRuartEnterCritical(pHalRuartAdapter);
ret = HalRuartDmaRecv(pHalRuartAdapter, (u8*)prxbuf, len);
HalRuartExitCritical(pHalRuartAdapter);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
task_yield = (void (*)(void))force_cs;
pHalRuartAdapter->Status = HAL_UART_STATUS_OK;
while (pHalRuartAdapter->State & HAL_UART_STATE_BUSY_RX) {
if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) {
ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter);
ret = pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter);
pHalRuartAdapter->Status = HAL_UART_STATUS_TIMEOUT;
break;
}
if (NULL != task_yield) {
task_yield();
}
}
if (pHalRuartAdapter->Status == HAL_UART_STATUS_TIMEOUT) {
return (len - pHalRuartAdapter->RxCount);
} else {
return len;
}
} else {
return (-ret);
}
}
#endif // end of "#ifdef CONFIG_GDMA_EN"
int32_t serial_send_stream_abort (serial_t *obj)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
HalRuartEnterCritical(pHalRuartAdapter);
ret = pHalRuartOp->HalRuartStopSend((VOID*)pHalRuartAdapter);
HalRuartExitCritical(pHalRuartAdapter);
if (HAL_OK != ret) {
return -ret;
}
HalRuartResetTxFifo((VOID*)pHalRuartAdapter);
ret = obj->tx_len - pHalRuartAdapter->TxCount;
return (ret);
}
int32_t serial_recv_stream_abort (serial_t *obj)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
int ret;
pHalRuartOp = &(obj->hal_uart_op);
HalRuartEnterCritical(pHalRuartAdapter);
ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter);
HalRuartExitCritical(pHalRuartAdapter);
if (HAL_OK != ret) {
return -ret;
}
// pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter);
ret = obj->rx_len - pHalRuartAdapter->RxCount;
return (ret);
}
void serial_disable (serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
HalRuartDisable((VOID*)pHalRuartAdapter);
}
void serial_enable (serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
HalRuartEnable((VOID*)pHalRuartAdapter);
}
// return the byte count received before timeout, or error(<0)
int32_t serial_recv_stream_timeout (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms, void *force_cs)
{
PHAL_RUART_OP pHalRuartOp;
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp);
uint32_t TimeoutCount=0, StartCount;
int ret;
void (*task_yield)(void);
task_yield = NULL;
pHalRuartOp = &(obj->hal_uart_op);
HalRuartEnterCritical(pHalRuartAdapter);
ret = pHalRuartOp->HalRuartIntRecv(pHalRuartAdapter, (u8*)prxbuf, len);
HalRuartExitCritical(pHalRuartAdapter);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
task_yield = (void (*)(void))force_cs;
while (pHalRuartAdapter->State & HAL_UART_STATE_BUSY_RX) {
if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) {
ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter);
ret = pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter);
pHalRuartAdapter->Status = HAL_UART_STATUS_TIMEOUT;
break;
}
if (NULL != task_yield) {
task_yield();
}
}
return (len - pHalRuartAdapter->RxCount);
} else {
return (-ret);
}
}
// to hook lock/unlock function for multiple-thread application
void serial_hook_lock(serial_t *obj, void *lock, void *unlock, uint32_t id)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
pHalRuartAdapter = &(obj->hal_uart_adp);
pHalRuartAdapter->EnterCritical = (void (*)(void))lock;
pHalRuartAdapter->ExitCritical = (void (*)(void))unlock;
}
// to read Line-Status register
// Bit 0: RX Data Ready
// Bit 1: Overrun Error
// Bit 2: Parity Error
// Bit 3: Framing Error
// Bit 4: Break Interrupt (received data input is held in 0 state for a longer than a full word tx time)
// Bit 5: TX FIFO empty (THR empty)
// Bit 6: TX FIFO empty (THR & TSR both empty)
// Bit 7: RX Error (parity error, framing error or break indication)
uint8_t serial_raed_lsr(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
uint8_t RegValue;
pHalRuartAdapter = &(obj->hal_uart_adp);
RegValue = HAL_RUART_READ8(pHalRuartAdapter->UartIndex, RUART_LINE_STATUS_REG_OFF);
return RegValue;
}
// to read Modem-Status register
// Bit 0: DCTS, The CTS line has changed its state
// Bit 1: DDSR, The DSR line has changed its state
// Bit 2: TERI, RI line has changed its state from low to high state
// Bit 3: DDCD, DCD line has changed its state
// Bit 4: Complement of the CTS input
// Bit 5: Complement of the DSR input
// Bit 6: Complement of the RI input
// Bit 7: Complement of the DCD input
uint8_t serial_raed_msr(serial_t *obj)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
uint8_t RegValue;
pHalRuartAdapter = &(obj->hal_uart_adp);
RegValue = HAL_RUART_READ8(pHalRuartAdapter->UartIndex, RUART_MODEM_STATUS_REG_OFF);
return RegValue;
}
// to set the RX FIFO level to trigger RX interrupt/RTS de-assert
// FifoLv:
// 0: 1-Byte
// 1: 4-Byte
// 2: 8-Byte
// 3: 14-Byte
void serial_rx_fifo_level(serial_t *obj, SerialFifoLevel FifoLv)
{
PHAL_RUART_ADAPTER pHalRuartAdapter;
uint8_t RegValue;
pHalRuartAdapter = &(obj->hal_uart_adp);
RegValue = (RUART_FIFO_CTL_REG_DMA_ENABLE | RUART_FIFO_CTL_REG_FIFO_ENABLE) | (((uint8_t)FifoLv&0x03) << 6);
HAL_RUART_WRITE8(pHalRuartAdapter->UartIndex, RUART_FIFO_CTL_REG_OFF, RegValue);
}
#endif

View file

@ -0,0 +1,290 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "sleep_ex_api.h"
#include "cmsis.h"
extern VOID SleepCG(u8 Option, u32 SDuration, u8 ClkSourceEn, u8 SDREn);
extern VOID DeepStandby(u8 Option, u32 SDuration, u8 GpioOption);
extern VOID DeepSleep(u8 Option, u32 SDuration);
SLEEP_WAKEUP_EVENT DStandbyWakeupEvent={0};
/**
* @brief To make the system entering the Clock Gated power saving.
* This function just make the system to enter the clock gated
* power saving mode and pending on wake up event waitting.
* The user application need to configure the peripheral to
* generate system wake up event, like GPIO interrupt
* , G-Timer timeout, etc. befor entering power saving mode.
*
* @param wakeup_event: A bit map of wake up event. Available event:
* SLEEP_WAKEUP_BY_STIMER
* SLEEP_WAKEUP_BY_GTIMER
* SLEEP_WAKEUP_BY_GPIO_INT
* SLEEP_WAKEUP_BY_WLAN
* SLEEP_WAKEUP_BY_NFC
* SLEEP_WAKEUP_BY_SDIO
* SLEEP_WAKEUP_BY_USB
* sleep_duration: the system sleep duration in ms, only valid
* for SLEEP_WAKEUP_BY_STIMER wake up event.
*
* @retval None
*/
void sleep_ex(uint32_t wakeup_event, uint32_t sleep_duration)
{
u8 wake_ev=0;
wake_ev = wakeup_event & 0xff;
if (sleep_duration == 0) {
wake_ev &= ~SLP_STIMER;
}
if (wake_ev == 0) {
// error: No wakeup event, skip the entering sleep mode
return;
}
SleepCG(wake_ev, sleep_duration, 0, 0); // same as old configuration: SCLK off & SDR no power off
}
/**
* @brief To make the system entering the Clock Gated power saving.
* This function just make the system to enter the clock gated
* power saving mode and pending on wake up event waitting.
* The user application need to configure the peripheral to
* generate system wake up event, like GPIO interrupt
* , G-Timer timeout, etc. befor entering power saving mode.
*
* @param wakeup_event: A bit map of wake up event. Available event:
* SLEEP_WAKEUP_BY_STIMER
* SLEEP_WAKEUP_BY_GTIMER
* SLEEP_WAKEUP_BY_GPIO_INT
* SLEEP_WAKEUP_BY_WLAN
* SLEEP_WAKEUP_BY_NFC
* SLEEP_WAKEUP_BY_SDIO
* SLEEP_WAKEUP_BY_USB
* sleep_duration: the system sleep duration in ms, only valid
* for SLEEP_WAKEUP_BY_STIMER wake up event.
* clk_sourec_enable: the option for SCLK on(1)/off(0)
* sdr_enable: the option for turn off the SDR controller (1:off, 0:on)
*
* @retval None
*/
void sleep_ex_selective(uint32_t wakeup_event, uint32_t sleep_duration, uint32_t clk_sourec_enable, uint32_t sdr_enable)
{
u8 wake_ev=0;
u8 sdr_en=0;
u8 clk_source_en=0;
wake_ev = wakeup_event & 0xff;
sdr_en = sdr_enable & 0xff;
clk_source_en = clk_sourec_enable & 0xff;
if (sleep_duration == 0) {
wake_ev &= ~SLP_STIMER;
}
if (wake_ev == 0) {
// error: No wakeup event, skip the entering sleep mode
return;
}
SleepCG(wake_ev, sleep_duration, clk_source_en, sdr_en);
}
/**
* @brief To add a wake up event to wake up the system from the
* deep standby power saving mode.
*
* @param wakeup_event: A bit map of wake up event. Available event:
* STANDBY_WAKEUP_BY_STIMER
* STANDBY_WAKEUP_BY_NFC
* STANDBY_WAKEUP_BY_PA5 (GPIO)
* STANDBY_WAKEUP_BY_PC7 (GPIO)
* STANDBY_WAKEUP_BY_PD5 (GPIO)
* STANDBY_WAKEUP_BY_PE3 (GPIO)
* sleep_duration_ms: the system sleep duration in ms, only valid
* for STANDBY_WAKEUP_BY_STIMER wake up event.
* gpio_active: for a GPIO pin to wake up the system by
* goes high(1) or low(0)
*
* @retval None
*/
void standby_wakeup_event_add(uint32_t wakeup_event, uint32_t sleep_duration_ms, uint32_t gpio_active)
{
u32 i;
u8 gpio_event;
u8 gpio_en;
u8 gpio_act;
if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) {
DStandbyWakeupEvent.wakeup_event |= DSTBY_STIMER;
DStandbyWakeupEvent.timer_duration = sleep_duration_ms;
}
#if 0
if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) {
DStandbyWakeupEvent.wakeup_event |= DSTBY_TIMER33;
// TODO: Sleep Duration ?
}
#endif
if (wakeup_event & STANDBY_WAKEUP_BY_NFC) {
DStandbyWakeupEvent.wakeup_event |= DSTBY_NFC;
}
gpio_event = STANDBY_WAKEUP_BY_PA5;
gpio_en = BIT0;
gpio_act = BIT4;
// Loop 4 to check 4 GPIO wake up event
for (i=0;i<4;i++) {
if (wakeup_event & gpio_event) {
DStandbyWakeupEvent.wakeup_event |= DSTBY_GPIO;
DStandbyWakeupEvent.gpio_option |= gpio_en;
if (gpio_active) {
// Active High
DStandbyWakeupEvent.gpio_option |= gpio_act;
}
else {
// Active Low
DStandbyWakeupEvent.gpio_option &= ~gpio_act;
}
}
gpio_event = gpio_event << 1;
gpio_en = gpio_en << 1;
gpio_act = gpio_act << 1;
}
}
/**
* @brief To delete a wake up event for wakeing up the system from the
* deep standby power saving mode.
*
* @param wakeup_event: A bit map of wake up event. Available event:
* STANDBY_WAKEUP_BY_STIMER
* STANDBY_WAKEUP_BY_NFC
* STANDBY_WAKEUP_BY_PA5 (GPIO)
* STANDBY_WAKEUP_BY_PC7 (GPIO)
* STANDBY_WAKEUP_BY_PD5 (GPIO)
* STANDBY_WAKEUP_BY_PE3 (GPIO)
* @retval None
*/
void standby_wakeup_event_del(uint32_t wakeup_event)
{
if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) {
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_STIMER;
}
#if 0
if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) {
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_TIMER33;
}
#endif
if (wakeup_event & STANDBY_WAKEUP_BY_NFC) {
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_NFC;
}
if (wakeup_event & STANDBY_WAKEUP_BY_PA5) {
DStandbyWakeupEvent.gpio_option &= ~BIT0;
}
if (wakeup_event & STANDBY_WAKEUP_BY_PC7) {
DStandbyWakeupEvent.gpio_option &= ~BIT1;
}
if (wakeup_event & STANDBY_WAKEUP_BY_PD5) {
DStandbyWakeupEvent.gpio_option &= ~BIT2;
}
if (wakeup_event & STANDBY_WAKEUP_BY_PE3) {
DStandbyWakeupEvent.gpio_option &= ~BIT3;
}
if ((DStandbyWakeupEvent.gpio_option & 0x0f) == 0) {
// All GPIO wake up pin are disabled
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_GPIO;
}
}
/**
* @brief To make the system entering the Deep Standby power saving.
* The CPU, memory and part fo peripheral power is off when
* entering deep standby power saving mode. The program needs
* to be reload from the flash at system resume.
*
* @retval None
*/
void deepstandby_ex(void)
{
if ((DStandbyWakeupEvent.wakeup_event & (DSTBY_STIMER|DSTBY_NFC|DSTBY_GPIO)) == 0) {
// error: no wakeup event was added, so skip the entering standby power saving
return;
}
DeepStandby(DStandbyWakeupEvent.wakeup_event,
DStandbyWakeupEvent.timer_duration, DStandbyWakeupEvent.gpio_option);
}
/**
* @brief To make the system entering the Deep Sleep power saving mode.
* The CPU, memory and peripheral power is off when entering
* deep sleep power saving mode. The program needs to be reload
* and all peripheral needs be re-configure when system resume.
*
* @param wakeup_event: A bit map of wake up event. Available event:
* DSLEEP_WAKEUP_BY_TIMER
* DSLEEP_WAKEUP_BY_GPIO
* sleep_duration: the system sleep duration in ms, only valid
* for DSLEEP_WAKEUP_BY_TIMER wake up event.
*
* @retval None
*/
void deepsleep_ex(uint32_t wakeup_event, uint32_t sleep_duration)
{
u8 wake_ev=0;
if ((wakeup_event & DSLEEP_WAKEUP_BY_TIMER) && (sleep_duration > 0)) {
// wake up by timeout
wake_ev |= DS_TIMER33;
}
if (wakeup_event & DSLEEP_WAKEUP_BY_GPIO) {
// wake up by GPIO pin goes high
wake_ev |= DS_GPIO;
}
if (wake_ev == 0) {
// error: No wake up event, skip entering deep sleep mode
return;
}
DeepSleep (wake_ev, sleep_duration);
}

View file

@ -0,0 +1,87 @@
#include <spdio_api.h>
#include "hal_sdio.h"
#if 0 // - HalSdioRegisterTxCallback(spdio_rx_done_cb, (void *)obj); // ?????????? HalSdioRegisterRxDoneCallback(spdio_tx_done_cb, (void *)obj); // ?????????
struct spdio_t *g_spdio_priv = NULL;
s8 spdio_rx_done_cb(void *padapter, u8 *data, u16 offset, u16 pktsize, u8 type){
struct spdio_buf_t *buf = (struct spdio_buf_t *)data;
struct spdio_t *obj = (struct spdio_t *)padapter;
if(obj)
return obj->rx_done_cb(obj, buf, (u8 *)(buf->buf_addr+offset), pktsize, type);
else
SPDIO_API_PRINTK("spdio rx done callback function is null!");
return SUCCESS;
}
s8 spdio_tx_done_cb(void *padapter, u8 *data, u16 offset, u16 pktsize, u8 type){
struct spdio_t *obj = (struct spdio_t *)padapter;
struct spdio_buf_t *buf = (struct spdio_buf_t *)data;
if(obj)
return obj->tx_done_cb(obj, buf);
else
SPDIO_API_PRINTK("spdio tx done callback function is null!");
return SUCCESS;
}
s8 spdio_tx(struct spdio_t *obj, struct spdio_buf_t *pbuf){
extern s8 HalSdioRxCallback(PHAL_SDIO_ADAPTER pSDIODev, VOID *pData, u16 Offset, u16 PktSize, u8 CmdType);
return HalSdioRxCallback((u8 *)pbuf, 0, pbuf->buf_size, pbuf->type); // ?????????
}
void spdio_structinit(struct spdio_t *obj){
obj->rx_bd_bufsz = SPDIO_RX_BUFSZ_ALIGN(2048+24); //extra 24 bytes for sdio header
obj->rx_bd_num = 24;
obj->tx_bd_num = 24;
obj->priv = NULL;
obj->rx_buf = NULL;
obj->rx_done_cb = NULL;
obj->tx_done_cb = NULL;
}
///////// Add pvvx, no ...
void HalSdioRegisterRxCallback(char (*rx_done_cb)(void *priv, void* pbuf, u8 *pdata, u16 size, u8 type), void *obj)
{
struct spdio_t * sp = (struct spdio_t *) obj;
sp->rx_done_cb = rx_done_cb;
}
void HalSdioRegisterTxDoneCallback(char (*tx_done_cb)(void *priv, void* pbuf), void *obj)
{
struct spdio_t * sp = (struct spdio_t *) obj;
sp->tx_done_cb = tx_done_cb;
}
///////
void spdio_init(struct spdio_t *obj)
{
if(obj == NULL){
SPDIO_API_PRINTK("spdio obj is NULL, spdio init failed!");
return;
}
if((obj->rx_bd_num == 0) ||(obj->rx_bd_bufsz == 0) || (obj->rx_bd_bufsz%64)
||(obj->tx_bd_num == 0) ||(obj->tx_bd_num%2)||(obj->rx_buf == NULL))
{
SPDIO_API_PRINTK("spdio obj resource isn't correctly inited, spdio init failed!");
return;
}
g_spdio_priv = obj;
HalSdioInit();
HalSdioRegisterRxCallback(spdio_rx_done_cb, (void *)obj); // ??????????
HalSdioRegisterTxDoneCallback(spdio_tx_done_cb, (void *)obj); // ?????????
}
void spdio_deinit(struct spdio_t *obj)
{
if(obj == NULL){
SPDIO_API_PRINTK("spdio obj is NULL, spdio deinit failed");
return;
}
HalSdioDeInit();
g_spdio_priv = NULL;
}
#endif

View file

@ -0,0 +1,968 @@
#include "objects.h"
#include "spi_api.h"
#include "spi_ex_api.h"
#include "PinNames.h"
#include "pinmap.h"
#include "hal_ssi.h"
extern u32 SystemGetCpuClk(VOID);
extern VOID HAL_GPIO_PullCtrl(u32 pin, u32 mode);
void spi_tx_done_callback(VOID *obj);
void spi_rx_done_callback(VOID *obj);
void spi_bus_tx_done_callback(VOID *obj);
#ifdef CONFIG_GDMA_EN
HAL_GDMA_OP SpiGdmaOp;
#endif
uint8_t SPI0_IS_AS_SLAVE = 0;
//TODO: Load default Setting: It should be loaded from external setting file.
extern const DW_SSI_DEFAULT_SETTING SpiDefaultSetting;
static const PinMap PinMap_SSI_MOSI[] = {
{PE_2, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)},
{PC_2, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)},
{PA_1, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)},
{PB_6, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)},
{PD_6, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)},
{PG_2, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)},
{PE_6, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)},
{PD_2, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)},
{NC, NC, 0}
};
static const PinMap PinMap_SSI_MISO[] = {
{PE_3, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)},
{PC_3, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)},
{PA_0, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)},
{PB_7, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)},
{PD_7, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)},
{PG_3, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)},
{PE_7, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)},
{PD_3, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)},
{NC, NC, 0}
};
void spi_init (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
SSI_DBG_ENTRANCE("spi_init()\n");
uint32_t ssi_mosi, ssi_miso, ssi_peri;
uint8_t ssi_idx, ssi_pinmux;
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
_memset((void*)obj, 0, sizeof(spi_t));
obj->state = 0;
uint32_t SystemClock = SystemGetCpuClk();
uint32_t MaxSsiFreq = (SystemClock >> 2) >> 1;
/* SsiClockDivider doesn't support odd number */
DBG_SSI_INFO("SystemClock: %d\n", SystemClock);
DBG_SSI_INFO("MaxSsiFreq : %d\n", MaxSsiFreq);
ssi_mosi = pinmap_peripheral(mosi, PinMap_SSI_MOSI);
ssi_miso = pinmap_peripheral(miso, PinMap_SSI_MISO);
//DBG_SSI_INFO("ssi_mosi: %d, ssi_miso: %d\n", ssi_mosi, ssi_miso);
ssi_peri = pinmap_merge(ssi_mosi, ssi_miso);
if (unlikely(ssi_peri == NC)) {
DBG_SSI_ERR("spi_init(): Cannot find matched SSI index.\n");
return;
}
obj->sclk = (u8)sclk;
ssi_idx = RTL_GET_PERI_IDX(ssi_peri);
ssi_pinmux = RTL_GET_PERI_SEL(ssi_peri);
DBG_SSI_INFO("ssi_peri: %d, ssi_idx: %d, ssi_pinmux: %d\n", ssi_peri, ssi_idx, ssi_pinmux);
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
pHalSsiAdaptor->Index = ssi_idx;
pHalSsiAdaptor->PinmuxSelect = ssi_pinmux;
#if 0
// XXX: Only for test
if ((ssi_idx == 0) && (SPI0_IS_AS_SLAVE == 1)) {
//DBG_SSI_INFO("SSI%d will be as slave. (spi0_is_slave: %d)\n", index, spi0_is_slave);
pHalSsiAdaptor->Role = SSI_SLAVE;
}
else
#endif
{
//DBG_SSI_INFO("SSI%d will be as master. (spi0_is_slave: %d)\n", index, spi0_is_slave);
pHalSsiAdaptor->Role = SSI_MASTER;
}
HalSsiOpInit((VOID*)pHalSsiOp);
pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role);
/* Pinmux workaround */
if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOC)) {
EEPROM_PIN_CTRL(OFF);
}
if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOE)) {
DBG_SSI_WARN(ANSI_COLOR_MAGENTA"SPI0 Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET);
}
//pHalSsiOp->HalSsiPinmuxEnable(pHalSsiAdaptor);
//TODO: Implement default setting structure.
pHalSsiOp->HalSsiLoadSetting(pHalSsiAdaptor, (void*)&SpiDefaultSetting);
pHalSsiAdaptor->DefaultRxThresholdLevel = SpiDefaultSetting.RxThresholdLevel;
//pHalSsiOp->HalSsiInit(pHalSsiAdaptor);
if(HalSsiInit(pHalSsiAdaptor) != HAL_OK){
DBG_SSI_ERR(ANSI_COLOR_RED"spi_init(): SPI %x init fails.\n"ANSI_COLOR_RESET,pHalSsiAdaptor->Index);
return;
}
pHalSsiAdaptor->TxCompCallback = spi_tx_done_callback;
pHalSsiAdaptor->TxCompCbPara = (void*)obj;
pHalSsiAdaptor->RxCompCallback = spi_rx_done_callback;
pHalSsiAdaptor->RxCompCbPara = (void*)obj;
pHalSsiAdaptor->TxIdleCallback = spi_bus_tx_done_callback;
pHalSsiAdaptor->TxIdleCbPara = (void*)obj;
#ifdef CONFIG_GDMA_EN
HalGdmaOpInit((VOID*)&SpiGdmaOp);
pHalSsiAdaptor->DmaConfig.pHalGdmaOp = &SpiGdmaOp;
pHalSsiAdaptor->DmaConfig.pRxHalGdmaAdapter = &obj->spi_gdma_adp_rx;
pHalSsiAdaptor->DmaConfig.pTxHalGdmaAdapter = &obj->spi_gdma_adp_tx;
obj->dma_en = 0;
pHalSsiAdaptor->HaveTxChannel = 0;
pHalSsiAdaptor->HaveRxChannel = 0;
#endif
}
void spi_free (spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
//PHAL_SSI_OP pHalSsiOp;
pHalSsiAdaptor = &obj->spi_adp;
//pHalSsiOp = &obj->spi_op;
//pHalSsiOp->HalSsiInterruptDisable(pHalSsiAdaptor);
//pHalSsiOp->HalSsiDisable(pHalSsiAdaptor);
//pHalSsiOp->HalSsiPinmuxDisable(pHalSsiAdaptor);
HalSsiDeInit(pHalSsiAdaptor);
SPI0_MULTI_CS_CTRL(OFF);
#ifdef CONFIG_GDMA_EN
if (obj->dma_en & SPI_DMA_RX_EN) {
HalSsiRxGdmaDeInit(pHalSsiAdaptor);
}
if (obj->dma_en & SPI_DMA_TX_EN) {
HalSsiTxGdmaDeInit(pHalSsiAdaptor);
}
obj->dma_en = 0;
#endif
}
void spi_format (spi_t *obj, int bits, int mode, int slave)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
pHalSsiAdaptor->DataFrameSize = (bits - 1);
/*
* mode | POL PHA
* -----+--------
* 0 | 0 0
* 1 | 0 1
* 2 | 1 0
* 3 | 1 1
*
* SCPOL_INACTIVE_IS_LOW = 0,
* SCPOL_INACTIVE_IS_HIGH = 1
*
* SCPH_TOGGLES_IN_MIDDLE = 0,
* SCPH_TOGGLES_AT_START = 1
*/
switch (mode)
{
case 0:
pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW;
pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE;
break;
case 1:
pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW;
pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
break;
case 2:
pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE;
break;
case 3:
pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
break;
default: // same as 3
pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
break;
}
if (slave == 1) {
if (pHalSsiAdaptor->Index == 0) {
pHalSsiAdaptor->Role = SSI_SLAVE;
pHalSsiAdaptor->SlaveOutputEnable = SLV_TXD_ENABLE; // <-- Slave only
SPI0_IS_AS_SLAVE = 1;
DBG_SSI_INFO("SPI0 is as slave\n");
}
else {
DBG_SSI_ERR("The SPI%d cannot work as Slave mode, only SPI0 does.\r\n", pHalSsiAdaptor->Index);
pHalSsiAdaptor->Role = SSI_MASTER;
}
}
else {
pHalSsiAdaptor->Role = SSI_MASTER;
}
pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role);
#ifdef CONFIG_GPIO_EN
if (pHalSsiAdaptor->Role == SSI_SLAVE) {
if (pHalSsiAdaptor->SclkPolarity == SCPOL_INACTIVE_IS_LOW) {
HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullDown);
}
else {
HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullUp);
}
}
#endif
HalSsiSetFormat(pHalSsiAdaptor);
}
void spi_frequency (spi_t *obj, int hz)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
pHalSsiAdaptor = &obj->spi_adp;
HalSsiSetSclk(pHalSsiAdaptor, (u32)hz);
}
void spi_slave_select(spi_t *obj, ChipSelect slaveindex)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
u8 Index;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
Index = pHalSsiAdaptor->Index;
if((pHalSsiAdaptor->Role == SSI_MASTER) && (Index == 0)){
pHalSsiOp->HalSsiSetSlaveEnableRegister((VOID*)pHalSsiAdaptor,slaveindex);
if(slaveindex != CS_0){
SPI0_MULTI_CS_CTRL(ON);
}
}
else{
DBG_SSI_ERR("Only SPI 0 master mode supports slave selection.\n");
}
}
void spi_slave_select_bypin(spi_t *obj, PinName pinname)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
u8 Index;
u8 slaveindex = 8;
u8 pinmux;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
Index = pHalSsiAdaptor->Index;
pinmux = pHalSsiAdaptor->PinmuxSelect;
if((pHalSsiAdaptor->Role == SSI_MASTER) && (Index == 0)){
if(pinmux == S0){
switch (pinname){
case PE_0:
slaveindex = CS_0;
break;
case PE_4:
slaveindex = CS_1;
break;
case PE_5:
slaveindex = CS_2;
break;
case PE_6:
slaveindex = CS_3;
break;
case PE_7:
slaveindex = CS_4;
break;
case PE_8:
slaveindex = CS_5;
break;
case PE_9:
slaveindex = CS_6;
break;
case PE_A:
slaveindex = CS_7;
break;
default:
slaveindex = 8;
}
}
if(pinmux == S1){
switch (pinname){
case PC_0:
slaveindex = CS_0;
break;
case PC_4:
slaveindex = CS_1;
break;
case PC_5:
slaveindex = CS_2;
break;
case PC_6:
slaveindex = CS_3;
break;
case PC_7:
slaveindex = CS_4;
break;
case PC_8:
slaveindex = CS_5;
break;
case PC_9:
slaveindex = CS_6;
break;
default:
slaveindex = 8;
}
}
if(slaveindex != 8){
pHalSsiOp->HalSsiSetSlaveEnableRegister((VOID*)pHalSsiAdaptor,slaveindex);
if(slaveindex != CS_0){
SPI0_MULTI_CS_CTRL(ON);
}
}
else
DBG_SSI_ERR("Wrong Chip Select Pin.\n");
}
else{
DBG_SSI_ERR("Only SPI 0 master mode supports slave selection.\n");
}
}
static inline void ssi_write (spi_t *obj, int value)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
while (!pHalSsiOp->HalSsiWriteable(pHalSsiAdaptor));
pHalSsiOp->HalSsiWrite((VOID*)pHalSsiAdaptor, value);
}
static inline int ssi_read(spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
while (!pHalSsiOp->HalSsiReadable(pHalSsiAdaptor));
return (int)pHalSsiOp->HalSsiRead(pHalSsiAdaptor);
}
int spi_master_write (spi_t *obj, int value)
{
ssi_write(obj, value);
return ssi_read(obj);
}
int spi_slave_receive (spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int Readable;
int Busy;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
Readable = pHalSsiOp->HalSsiReadable(pHalSsiAdaptor);
Busy = (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor);
return ((Readable && !Busy) ? 1 : 0);
}
int spi_slave_read (spi_t *obj)
{
return ssi_read(obj);
}
void spi_slave_write (spi_t *obj, int value)
{
ssi_write(obj, value);
}
int spi_busy (spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
return (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor);
}
void spi_flush_rx_fifo (spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
u32 rx_fifo_level;
u32 i;
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
while(pHalSsiOp->HalSsiReadable(pHalSsiAdaptor)){
rx_fifo_level = pHalSsiOp->HalSsiGetRxFifoLevel(pHalSsiAdaptor);
for(i=0;i<rx_fifo_level;i++) {
pHalSsiOp->HalSsiRead(pHalSsiAdaptor);
}
}
}
// Slave mode read a sequence of data by interrupt mode
int32_t spi_slave_read_stream(spi_t *obj, char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_slave_read_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
//DBG_SSI_INFO("rx_buffer addr: %X, length: %d\n", rx_buffer, length);
obj->state |= SPI_STATE_RX_BUSY;
if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
return ret;
}
// Slave mode write a sequence of data by interrupt mode
int32_t spi_slave_write_stream(spi_t *obj, char *tx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_TX_BUSY) {
DBG_SSI_WARN("spi_slave_write_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
obj->state |= SPI_STATE_TX_BUSY;
if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_TX_BUSY;
}
return ret;
}
// Master mode read a sequence of data by interrupt mode
// The length unit is byte, for both 16-bits and 8-bits mode
int32_t spi_master_read_stream(spi_t *obj, char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_master_read_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
// wait bus idle
while(pHalSsiOp->HalSsiBusy(pHalSsiAdaptor));
obj->state |= SPI_STATE_RX_BUSY;
if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) == HAL_OK) {
/* as Master mode, it need to push data to TX FIFO to generate clock out
then the slave can transmit data out */
// send some dummy data out
if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, NULL, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
}
else {
obj->state &= ~SPI_STATE_RX_BUSY;
}
return ret;
}
// Master mode write a sequence of data by interrupt mode
// The length unit is byte, for both 16-bits and 8-bits mode
int32_t spi_master_write_stream(spi_t *obj, char *tx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_TX_BUSY) {
DBG_SSI_WARN("spi_master_write_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
obj->state |= SPI_STATE_TX_BUSY;
/* as Master mode, sending data will receive data at sametime, so we need to
drop those received dummy data */
if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_TX_BUSY;
}
return ret;
}
// Master mode write a sequence of data by interrupt mode
// The length unit is byte, for both 16-bits and 8-bits mode
int32_t spi_master_write_read_stream(spi_t *obj, char *tx_buffer,
char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & (SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY)) {
DBG_SSI_WARN("spi_master_write_and_read_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
// wait bus idle
while(pHalSsiOp->HalSsiBusy(pHalSsiAdaptor));
obj->state |= SPI_STATE_RX_BUSY;
/* as Master mode, sending data will receive data at sametime */
if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) == HAL_OK) {
obj->state |= SPI_STATE_TX_BUSY;
if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) {
obj->state &= ~(SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY);
// Disable RX IRQ
pHalSsiAdaptor->InterruptMask &= ~(BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM);
pHalSsiOp->HalSsiSetInterruptMask((VOID*)pHalSsiAdaptor);
}
}
else {
obj->state &= ~(SPI_STATE_RX_BUSY);
}
return ret;
}
int32_t spi_slave_read_stream_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int ret,timeout = 0;
uint32_t StartCount, TimeoutCount = 0;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_slave_read_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
obj->state |= SPI_STATE_RX_BUSY;
HalSsiEnterCritical(pHalSsiAdaptor);
if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
HalSsiExitCritical(pHalSsiAdaptor);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
while (obj->state & SPI_STATE_RX_BUSY) {
if (HAL_TIMEOUT == HalSsiTimeout(StartCount, TimeoutCount)) {
ret = HalSsiStopRecv(pHalSsiAdaptor);
obj->state &= ~ SPI_STATE_RX_BUSY;
timeout = 1;
DBG_SSI_INFO("Slave is timeout\n");
break;
}
}
if ((pHalSsiAdaptor->DataFrameSize + 1) > 8){
pHalSsiAdaptor->RxLength <<= 1;
}
if(timeout)
return (length - pHalSsiAdaptor->RxLength);
else
return length;
}
else {
return (-ret);
}
}
// Bus Idle: Real TX done, TX FIFO empty and bus shift all data out already
void spi_bus_tx_done_callback(VOID *obj)
{
spi_t *spi_obj = (spi_t *)obj;
spi_irq_handler handler;
if (spi_obj->bus_tx_done_handler) {
handler = (spi_irq_handler)spi_obj->bus_tx_done_handler;
handler(spi_obj->bus_tx_done_irq_id, 0);
}
}
void spi_tx_done_callback(VOID *obj)
{
spi_t *spi_obj = (spi_t *)obj;
spi_irq_handler handler;
if (spi_obj->state & SPI_STATE_TX_BUSY) {
spi_obj->state &= ~SPI_STATE_TX_BUSY;
if (spi_obj->irq_handler) {
handler = (spi_irq_handler)spi_obj->irq_handler;
handler(spi_obj->irq_id, SpiTxIrq);
}
}
}
void spi_rx_done_callback(VOID *obj)
{
spi_t *spi_obj = (spi_t *)obj;
spi_irq_handler handler;
spi_obj->state &= ~SPI_STATE_RX_BUSY;
if (spi_obj->irq_handler) {
handler = (spi_irq_handler)spi_obj->irq_handler;
handler(spi_obj->irq_id, SpiRxIrq);
}
}
void spi_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id)
{
obj->irq_handler = (u32)handler;
obj->irq_id = (u32)id;
}
void spi_bus_tx_done_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id)
{
obj->bus_tx_done_handler = (u32)handler;
obj->bus_tx_done_irq_id = (u32)id;
}
void spi_enable(spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdapter;
pHalSsiAdapter = &obj->spi_adp;
HalSsiEnable((VOID*)pHalSsiAdapter);
}
void spi_disable(spi_t *obj)
{
PHAL_SSI_ADAPTOR pHalSsiAdapter;
pHalSsiAdapter = &obj->spi_adp;
HalSsiDisable((VOID*)pHalSsiAdapter);
}
#ifdef CONFIG_GDMA_EN
int32_t spi_slave_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_slave_read_stream_dma: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_RX_EN)==0) {
if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_RX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_RX_BUSY;
ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length);
if (ret != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
return (ret);
}
int32_t spi_slave_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_TX_BUSY) {
DBG_SSI_WARN("spi_slave_write_stream_dma: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_TX_EN)==0) {
if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_TX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_TX_BUSY;
ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length);
if (ret != HAL_OK) {
obj->state &= ~SPI_STATE_TX_BUSY;
}
return (ret);
}
int32_t spi_master_write_read_stream_dma(spi_t *obj, char *tx_buffer,
char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & (SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY)) {
DBG_SSI_WARN("spi_master_write_and_read_stream: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_TX_EN)==0) {
if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_TX_EN;
}
else {
return HAL_BUSY;
}
}
if ((obj->dma_en & SPI_DMA_RX_EN)==0) {
if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_RX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_RX_BUSY;
/* as Master mode, sending data will receive data at sametime */
if ((ret=HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length)) == HAL_OK) {
obj->state |= SPI_STATE_TX_BUSY;
if ((ret=HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) {
obj->state &= ~(SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY);
}
}
else {
obj->state &= ~(SPI_STATE_RX_BUSY);
}
return ret;
}
int32_t spi_master_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_master_read_stream_dma: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_RX_EN)==0) {
if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_RX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_RX_BUSY;
ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length);
if (ret != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
// for master mode, we need to send data to generate clock out
if (obj->dma_en & SPI_DMA_TX_EN) {
// TX DMA is on already, so use DMA to TX data
// Make the GDMA to use the rx_buffer too
ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) rx_buffer, length);
if (ret != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
}
else {
// TX DMA isn't enabled, so we just use Interrupt mode to TX dummy data
if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, NULL, length)) != HAL_OK) {
obj->state &= ~SPI_STATE_RX_BUSY;
}
}
return ret;
}
int32_t spi_master_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int32_t ret;
if (obj->state & SPI_STATE_TX_BUSY) {
DBG_SSI_WARN("spi_master_write_stream_dma: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_TX_EN)==0) {
if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_TX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_TX_BUSY;
ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length);
if (ret != HAL_OK) {
obj->state &= ~SPI_STATE_TX_BUSY;
}
return ret;
}
int32_t spi_slave_read_stream_dma_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms)
{
PHAL_SSI_ADAPTOR pHalSsiAdaptor;
PHAL_SSI_OP pHalSsiOp;
int ret,timeout = 0;
uint32_t StartCount, TimeoutCount = 0;
if (obj->state & SPI_STATE_RX_BUSY) {
DBG_SSI_WARN("spi_slave_read_stream_dma: state(0x%x) is not ready\r\n",
obj->state);
return HAL_BUSY;
}
pHalSsiAdaptor = &obj->spi_adp;
pHalSsiOp = &obj->spi_op;
if ((obj->dma_en & SPI_DMA_RX_EN)==0) {
if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) {
obj->dma_en |= SPI_DMA_RX_EN;
}
else {
return HAL_BUSY;
}
}
obj->state |= SPI_STATE_RX_BUSY;
HalSsiEnterCritical(pHalSsiAdaptor);
ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length);
HalSsiExitCritical(pHalSsiAdaptor);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
while (obj->state & SPI_STATE_RX_BUSY) {
if (HAL_TIMEOUT == HalSsiTimeout(StartCount, TimeoutCount)) {
ret = HalSsiStopRecv(pHalSsiAdaptor);
obj->state &= ~ SPI_STATE_RX_BUSY;
timeout = 1;
DBG_SSI_INFO("Slave is timeout\n");
break;
}
}
if(timeout)
return (length - pHalSsiAdaptor->RxLength);
else
return length;
}
else {
obj->state &= ~ SPI_STATE_RX_BUSY;
return (-ret);
}
}
#endif // end of "#ifdef CONFIG_GDMA_EN"

View file

@ -0,0 +1,230 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "cmsis.h"
#include "sys_api.h"
#include "flash_api.h"
#include "osdep_api.h"
#include "device_lock.h"
#define OTA_Signature "81958711"
#define OTA_Clear "00000000"
#define OTA_Signature_len 8
#define OTA_Signature_offset 8
#define OTA_valid_offset 0x100000
#define printf DiagPrintf
#if !defined(__ICCARM__)
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
#define memset(dst, val, sz) _memset(dst, val, sz)
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
#endif // #if !defined(__ICCARM__)
extern VOID HalJtagPinOff(VOID);
extern void HalInitLogUart(void);
extern void HalDeinitLogUart(void);
#ifdef CONFIG_SDR_EN
//#if defined ( __ICCARM__ )
extern u8 IsSdrPowerOn();
//#endif
#endif
/**
* @brief Turn off the JTAG function
*
* @return None
*
*/
void sys_jtag_off(void)
{
HalJtagPinOff();
}
void sys_clear_ota_signature(void)
{
flash_t flash;
u32 ota_offset=0xFFFFFFFF, part1_offset, part2_offset;
u8 signature[OTA_Signature_len+1];
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset);
part1_offset = (part1_offset&0xFFFF) * 1024;
flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature);
if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
ota_offset = part1_offset;
}
flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset);
flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature);
if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
ota_offset = part2_offset;
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
printf("OTA offset = 0x%08X\n", ota_offset);
if(ota_offset < OTA_valid_offset){
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
signature[OTA_Signature_len] = '\0';
printf("Signature = %s\n", signature);
if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
memcpy((char*)signature, OTA_Clear, OTA_Signature_len);
flash_stream_write(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
signature[OTA_Signature_len] = '\0';
printf("Signature = %s\n", signature);
printf("Clear OTA signature success.\n");
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
}
}
void sys_recover_ota_signature(void)
{
flash_t flash;
u32 ota_offset=0xFFFFFFFF, part1_offset, part2_offset;
u8 signature[OTA_Signature_len+1];
u8* pbuf;
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset);
part1_offset = (part1_offset&0xFFFF) * 1024;
flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature);
if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
ota_offset = part1_offset;
}
flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset);
flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature);
if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
ota_offset = part2_offset;
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
printf("OTA offset = 0x%08X\n", ota_offset);
if(ota_offset < OTA_valid_offset){
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
signature[OTA_Signature_len] = '\0';
printf("Signature = %s\n", signature);
if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
// backup
pbuf = RtlMalloc(FLASH_SECTOR_SIZE);
if(!pbuf) return;
flash_stream_read(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf);
memcpy((char*)pbuf+OTA_Signature_offset, OTA_Signature, OTA_Signature_len);
flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE);
flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
// Write
flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
flash_erase_sector(&flash, ota_offset);
flash_stream_write(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf);
flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
signature[OTA_Signature_len] = '\0';
printf("Signature = %s\n", signature);
RtlMfree(pbuf, FLASH_SECTOR_SIZE);
printf("Recover OTA signature success.\n");
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
}
}
void sys_log_uart_on(void)
{
HalInitLogUart();
}
void sys_log_uart_off(void)
{
HalDeinitLogUart();
}
void sys_adc_calibration(u8 write, u16 *offset, u16 *gain)
{
extern flash_t flash;
if(write){
// backup
u8 *pbuf = RtlMalloc(FLASH_SECTOR_SIZE);
if(!pbuf) return;
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf);
memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET, offset, 2);
memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET+2, gain, 2);
flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE);
flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
// Write
// flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
flash_erase_sector(&flash, FLASH_SYSTEM_DATA_ADDR);
flash_stream_write(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
RtlMfree(pbuf, FLASH_SECTOR_SIZE);
printf("Store ADC calibration success.\n");
}
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, FLASH_ADC_PARA_BASE, 2, (u8*)offset);
flash_stream_read(&flash, FLASH_ADC_PARA_BASE+2, 2, (u8*)gain);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
printf("ADC offset = 0x%04X, gain = 0x%04X.\n", *offset, *gain);
}
/**
* @brief system software reset
*
* @return None
*
*/
void sys_reset(void)
{
// Set processor clock to default before system reset
HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021);
HalDelayUs(100*1000);
// Cortex-M3 SCB->AIRCR
HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY
(HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP
(1 << 2)); // SYSRESETREQ
}
u8 sys_is_sdram_power_on(void)
{
#ifdef CONFIG_SDR_EN
// u8 ison = 0;
//#if defined ( __ICCARM__ )
return IsSdrPowerOn();
//#endif
// return ison;
#else
return 0;
#endif
}
void sys_sdram_off(void)
{
#ifdef CONFIG_SDR_EN
//#if defined ( __ICCARM__ )
if (IsSdrPowerOn()) {
SdrPowerOff();
}
//#endif
#endif
}

View file

@ -0,0 +1,156 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
//#include <stddef.h>
#include "timer_api.h"
//#include "PeripheralNames.h"
#if CONFIG_TIMER_EN
extern HAL_TIMER_OP HalTimerOp;
extern HAL_Status HalTimerInitRtl8195a_Patch(
IN VOID *Data
);
static void gtimer_timeout_handler (uint32_t tid)
{
gtimer_t *obj = (gtimer_t *)tid;
gtimer_irq_handler handler;
u8 timer_id = obj->hal_gtimer_adp.TimerId;
if (obj->handler != NULL) {
handler = (gtimer_irq_handler)obj->handler;
handler(obj->hid);
}
if (!obj->is_periodcal) {
gtimer_stop(obj);
}
if(timer_id < 2) {
// Timer0 | Timer1: clear ISR here
// Timer 2~7 ISR will be cleared in HAL
HalTimerClearIsr(timer_id);
}
}
void gtimer_init (gtimer_t *obj, uint32_t tid)
{
PTIMER_ADAPTER pTimerAdapter = &(obj->hal_gtimer_adp);
if ((tid == 1) || (tid == 6) || (tid == 7)) {
DBG_TIMER_ERR("gtimer_init: This timer is reserved for HAL driver\r\n", tid);
return;
}
if (tid > GTIMER_MAX) {
DBG_TIMER_ERR("gtimer_init: Invalid TimerId=%d\r\n", tid);
return;
}
pTimerAdapter->IrqDis = 0; // Enable Irq @ initial
pTimerAdapter->IrqHandle.IrqFun = (IRQ_FUN) gtimer_timeout_handler;
if(tid == 0) {
pTimerAdapter->IrqHandle.IrqNum = TIMER0_IRQ;
} else if(tid == 1) {
pTimerAdapter->IrqHandle.IrqNum = TIMER1_IRQ;
} else {
pTimerAdapter->IrqHandle.IrqNum = TIMER2_7_IRQ;
}
pTimerAdapter->IrqHandle.Priority = 0;
pTimerAdapter->IrqHandle.Data = (u32)obj;
pTimerAdapter->TimerId = (u8)tid;
pTimerAdapter->TimerIrqPriority = 0;
pTimerAdapter->TimerLoadValueUs = 0xFFFFFFFF; // Just a whatever value
pTimerAdapter->TimerMode = USER_DEFINED;
HalTimerInit ((VOID*) pTimerAdapter);
// gtimer_stop(obj); // HAL Initial will let the timer started, just stop it after initial
}
void gtimer_deinit (gtimer_t *obj)
{
PTIMER_ADAPTER pTimerAdapter = &(obj->hal_gtimer_adp);
HalTimerDeInit((void*)pTimerAdapter);
}
uint32_t gtimer_read_tick (gtimer_t *obj)
{
PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp;
return (HalTimerOp.HalTimerReadCount(pTimerAdapter->TimerId));
}
uint64_t gtimer_read_us (gtimer_t *obj)
{
uint64_t time_us;
time_us = gtimer_read_tick(obj)*1000000/32768;
return (time_us);
}
void gtimer_reload (gtimer_t *obj, uint32_t duration_us)
{
PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp;
HalTimerReLoad(pTimerAdapter->TimerId, duration_us);
}
void gtimer_start (gtimer_t *obj)
{
PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp;
u8 TimerId = pTimerAdapter->TimerId;
HalTimerEnable(TimerId);
#if 0
HalTimerOp.HalTimerEn(pTimerAdapter->TimerId);
HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF),
HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) | (BIT0));
#endif
}
void gtimer_start_one_shout (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid)
{
obj->is_periodcal = _FALSE;
obj->handler = handler;
obj->hid = hid;
gtimer_reload(obj, duration_us);
gtimer_start(obj);
}
void gtimer_start_periodical (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid)
{
obj->is_periodcal = _TRUE;
obj->handler = handler;
obj->hid = hid;
if (duration_us > GTIMER_TICK_US) {
// reload will takes extra 1 tick
duration_us -= GTIMER_TICK_US;
}
gtimer_reload(obj, duration_us);
gtimer_start(obj);
}
void gtimer_stop (gtimer_t *obj)
{
PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp;
// obj->handler = NULL;
// HalTimerOp.HalTimerDis(pTimerAdapter->TimerId);
HalTimerDisable(pTimerAdapter->TimerId);
}
#endif // end of "#if CONFIG_TIMER_EN"

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************/
#ifndef MBED_EXT_TIMER_API_EXT_H
#define MBED_EXT_TIMER_API_EXT_H
#include "device.h"
//#include "rtl8195a.h"
typedef void (*gtimer_irq_handler)(uint32_t id);
typedef struct gtimer_s gtimer_t;
enum {
TIMER0 = 2, // GTimer 2, share with PWM_3
TIMER1 = 3, // GTimer 3, share with PWM_0
TIMER2 = 4, // GTimer 4, share with PWM_1
TIMER3 = 5, // GTimer 5, share with PWM_2
TIMER4 = 0, // GTimer 0, share with software-RTC functions
GTIMER_MAX = 5
};
void gtimer_init (gtimer_t *obj, uint32_t tid);
void gtimer_deinit (gtimer_t *obj);
uint32_t gtimer_read_tick (gtimer_t *obj);
uint64_t gtimer_read_us (gtimer_t *obj);
void gtimer_reload (gtimer_t *obj, uint32_t duration_us);
void gtimer_start (gtimer_t *obj);
void gtimer_start_one_shout (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid);
void gtimer_start_periodical (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid);
void gtimer_stop (gtimer_t *obj);
#endif

View file

@ -0,0 +1,137 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
#define TICK_READ_FROM_CPU 0 // 1: read tick from CPU, 0: read tick from G-Timer
#define SYS_TIM_ID 1 // the G-Timer ID for System
#define APP_TIM_ID 6 // the G-Timer ID for Application
static int us_ticker_inited = 0;
static TIMER_ADAPTER Timer6Adapter;
extern HAL_TIMER_OP HalTimerOp;
/*
VOID _us_ticker_irq_handler(IN VOID *Data)
{
us_ticker_irq_handler();
}
*/
void us_ticker_init(void)
{
if (us_ticker_inited) return;
us_ticker_inited = 1;
// Initial a G-Timer
Timer6Adapter.IrqDis = 1; // Disable Irq
Timer6Adapter.IrqHandle.IrqFun = (IRQ_FUN) us_ticker_irq_handler;
Timer6Adapter.IrqHandle.IrqNum = TIMER2_7_IRQ;
Timer6Adapter.IrqHandle.Priority = 10;
Timer6Adapter.IrqHandle.Data = (u32)NULL;
Timer6Adapter.TimerId = APP_TIM_ID;
Timer6Adapter.TimerIrqPriority = 0;
Timer6Adapter.TimerLoadValueUs = 1;
Timer6Adapter.TimerMode = FREE_RUN_MODE; // Countdown Free Run
HalTimerOp.HalTimerInit((VOID*) &Timer6Adapter);
DBG_TIMER_INFO("%s: Timer_Id=%d\n", __FUNCTION__, APP_TIM_ID);
}
#if (!TICK_READ_FROM_CPU) || !defined(PLATFORM_FREERTOS)
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
uint32_t us_ticker_read()
{
uint32_t tick_cnt;
uint32_t ticks_125ms;
uint32_t ticks_remain;
uint64_t us_tick;
//1 Our G-timer resolution is ~31 us (1/32K), and is a countdown timer
// if (!us_ticker_inited) {
// us_ticker_init();
// }
tick_cnt = HalTimerOp.HalTimerReadCount(SYS_TIM_ID);
tick_cnt = 0xffffffff - tick_cnt; // it's a down counter
ticks_125ms = tick_cnt/(GTIMER_CLK_HZ/8);
ticks_remain = tick_cnt - (ticks_125ms*(GTIMER_CLK_HZ/8));
us_tick = ticks_125ms * 125000;
us_tick += (ticks_remain * 1000000)/GTIMER_CLK_HZ;
return ((uint32_t)us_tick);
}
#else
// if the system tick didn't be initialed, call delay function may got system hang
#define OS_CLOCK (200000000UL/6*5) // PLATFORM_CLOCK // CPU clock = 166.66 MHz
#define OS_TICK 1000 // OS ticks 1000/sec
#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
#define NVIC_ST_CTRL (*((volatile uint32_t *)0xE000E010))
#define NVIC_ST_RELOAD (*((volatile uint32_t *)0xE000E014))
#define NVIC_ST_CURRENT (*((volatile uint32_t *)0xE000E018))
extern uint32_t xTaskGetTickCount( void );
uint32_t us_ticker_read()
{
uint32_t tick_cnt;
uint32_t us_tick, ms;
static uint32_t last_us_tick=0;
ms = xTaskGetTickCount();
us_tick = (uint32_t)(ms*1000);
tick_cnt = OS_TRV - NVIC_ST_CURRENT;
us_tick += (uint32_t)((tick_cnt*1000)/(OS_TRV+1) );
if ( (last_us_tick > us_tick) && (last_us_tick < 0xFFFFFC00) ) {
us_tick += 1000;
}
last_us_tick = us_tick;
return us_tick;
}
#endif
void us_ticker_set_interrupt(timestamp_t timestamp)
{
uint32_t cur_time_us;
uint32_t time_def;
cur_time_us = us_ticker_read();
if ((uint32_t)timestamp >= cur_time_us) {
time_def = (uint32_t)timestamp - cur_time_us;
}
else {
time_def = 0xffffffff - cur_time_us + (uint32_t)timestamp;
}
if (time_def < TIMER_TICK_US) {
time_def = TIMER_TICK_US; // at least 1 tick
}
Timer6Adapter.IrqDis = 0; // Enable Irq
Timer6Adapter.TimerLoadValueUs = time_def;
Timer6Adapter.TimerMode = USER_DEFINED; // Countdown Free Run
HalTimerOp.HalTimerInit((VOID*) &Timer6Adapter);
}
void us_ticker_disable_interrupt(void)
{
HalTimerOp.HalTimerDis((u32)Timer6Adapter.TimerId);
}
void us_ticker_clear_interrupt(void)
{
HalTimerOp.HalTimerIrqClear((u32)Timer6Adapter.TimerId);
}

View file

@ -0,0 +1,94 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "cmsis.h"
#include "wdt_api.h"
extern VOID WDGInitial(u32 Period);
extern VOID WDGStart(VOID);
extern VOID WDGStop(VOID);
extern VOID WDGRefresh(VOID);
extern VOID WDGIrqInitial(VOID);
extern VOID WDGIrqCallBackReg(VOID *CallBack, u32 Id);
/**
* @brief Initial the watch dog time setting
*
* @param timeout_ms: the watch-dog timer timeout value, in ms.
* default action of timeout is to reset the whole system.
* @return None
*
*/
void watchdog_init(uint32_t timeout_ms)
{
WDGInitial(timeout_ms);
}
/**
* @brief Start the watchdog counting
*
* @param None
* @return None
*
*/
void watchdog_start(void)
{
WDGStart();
}
/**
* @brief Stop the watchdog counting
*
* @param None
* @return None
*
*/
void watchdog_stop(void)
{
WDGStop();
}
/**
* @brief Refresh the watchdog counting to prevent WDT timeout
*
* @param None
* @return None
*
*/
void watchdog_refresh(void)
{
WDGRefresh();
}
/**
* @brief Switch the watchdog timer to interrupt mode and
* register a watchdog timer timeout interrupt handler.
* The interrupt handler will be called when the watch-dog
* timer is timeout.
*
* @param handler: the callback function for WDT timeout interrupt.
* id: the parameter for the callback function
* @return None
*
*/
void watchdog_irq_init(wdt_irq_handler handler, uint32_t id)
{
WDGIrqCallBackReg((VOID*)handler, (u32)id);
WDGIrqInitial();
}