更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
#include "common_api.h"
#include "time.h"
#include "osasys.h"
void RTC_GetDateTime(Date_UserDataStruct *pDate, Time_UserDataStruct *pTime)
{
Tamp2UTC(time(NULL), pDate, pTime, 0);
}
static struct tm prvTM;
extern const uint32_t DayTable[2][12];
struct tm *__wrap_localtime (const time_t *_timer)
{
Time_UserDataStruct Time;
Date_UserDataStruct Date;
uint64_t Sec;
utc_timer_value_t *timeUtc = OsaSystemTimeReadUtc();
if (_timer)
{
Sec = *_timer;
Tamp2UTC(Sec + timeUtc->timeZone * 900, &Date, &Time, 0);
}
else
{
Tamp2UTC(timeUtc->UTCsecs + timeUtc->timeZone * 900, &Date, &Time, 0);
}
prvTM.tm_year = Date.Year - 1900;
prvTM.tm_mon = Date.Mon - 1;
prvTM.tm_mday = Date.Day;
prvTM.tm_hour = Time.Hour;
prvTM.tm_min = Time.Min;
prvTM.tm_sec = Time.Sec;
prvTM.tm_wday = Time.Week;
prvTM.tm_yday = Date.Day - 1;
prvTM.tm_yday += DayTable[IsLeapYear(Date.Year)][Date.Mon - 1];
return &prvTM;
}
struct tm *__wrap_gmtime (const time_t *_timer)
{
Time_UserDataStruct Time;
Date_UserDataStruct Date;
uint64_t Sec;
if (_timer)
{
Sec = *_timer;
Tamp2UTC(Sec, &Date, &Time, 0);
}
else
{
RTC_GetDateTime(&Date, &Time);
}
prvTM.tm_year = Date.Year - 1900;
prvTM.tm_mon = Date.Mon - 1;
prvTM.tm_mday = Date.Day;
prvTM.tm_hour = Time.Hour;
prvTM.tm_min = Time.Min;
prvTM.tm_sec = Time.Sec;
prvTM.tm_wday = Time.Week;
prvTM.tm_yday = Date.Day - 1;
prvTM.tm_yday += DayTable[IsLeapYear(Date.Year)][Date.Mon - 1];
return &prvTM;
}
clock_t __wrap_clock (void)
{
return GetSysTickMS()/1000;
}
time_t __wrap_time (time_t *_Time)
{
utc_timer_value_t *timeUtc = OsaSystemTimeReadUtc();
if (_Time != NULL) {
*_Time = timeUtc->UTCsecs;
}
return timeUtc->UTCsecs;
}

View File

@@ -0,0 +1,348 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* ADC操作
*
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#ifdef __LUATOS__
#include "luat_malloc.h"
#include "luat_msgbus.h"
#include "luat_timer.h"
#endif
#include "luat_adc.h"
#include "adc.h"
#include "hal_adc.h"
#include "ic.h"
#include "hal_trim.h"
/*
注意, 按硬件应用手册的描述, ADC0 对应的是 AIO3, ADC1 对应的 AIO4
而 VBAT和TEMP 则使用LuatOS定义的, 与硬件无关.
*/
typedef struct
{
LUAT_ADC_RANGE_E range;
AdcAioResDiv_e resdiv;
float ratio;
}adc_range_resdiv_map_item_t;
extern void delay_us(uint32_t us);
static uint8_t adc_state[4] = {0}; // 注意实际映射, 当前不支持 AIO1/AIO2的映射
static LUAT_ADC_RANGE_E adc_range[4] = {LUAT_ADC_AIO_RANGE_3_8, LUAT_ADC_AIO_RANGE_3_8, LUAT_ADC_VBAT_RANGE_5_3_RATIO, LUAT_ADC_VBAT_RANGE_5_3_RATIO};
static volatile uint32_t aio3ChannelResult = 0;
static volatile uint32_t aio4ChannelResult = 0;
static volatile uint32_t vbatChannelResult = 0;
static volatile uint32_t thermalChannelResult = 0;
static int adc_exist(int id) {
if (id >= 0 && id < 5)
return 1;
if (id == LUAT_ADC_CH_CPU || id == LUAT_ADC_CH_VBAT)
return 1;
return 0;
}
static int adc_range_to_resdiv(int id, int range, AdcAioResDiv_e *resdiv, float *ratio)
{
adc_range_resdiv_map_item_t map[]=
{
{LUAT_ADC_AIO_RANGE_1_2, ADC_AIO_RESDIV_RATIO_1, (float)1},
{LUAT_ADC_AIO_RANGE_1_4, ADC_AIO_RESDIV_RATIO_14OVER16, (float)16/14},
{LUAT_ADC_AIO_RANGE_1_6, ADC_AIO_RESDIV_RATIO_12OVER16, (float)16/12},
{LUAT_ADC_AIO_RANGE_1_9, ADC_AIO_RESDIV_RATIO_10OVER16, (float)16/10},
{LUAT_ADC_AIO_RANGE_2_4, ADC_AIO_RESDIV_RATIO_8OVER16, (float)16/8},
{LUAT_ADC_AIO_RANGE_2_7, ADC_AIO_RESDIV_RATIO_7OVER16, (float)16/7},
{LUAT_ADC_AIO_RANGE_3_2, ADC_AIO_RESDIV_RATIO_6OVER16, (float)16/6},
{LUAT_ADC_AIO_RANGE_3_8, ADC_AIO_RESDIV_RATIO_5OVER16, (float)16/5},
// 不再支持以下配置,无意义
// {LUAT_ADC_AIO_RANGE_4_8, ADC_AIO_RESDIV_RATIO_4OVER16, (float)16/4},
// {LUAT_ADC_AIO_RANGE_6_4, ADC_AIO_RESDIV_RATIO_3OVER16, (float)16/3},
// {LUAT_ADC_AIO_RANGE_9_6, ADC_AIO_RESDIV_RATIO_2OVER16, (float)16/2},
// {LUAT_ADC_AIO_RANGE_19_2, ADC_AIO_RESDIV_RATIO_1OVER16, (float)16/1},
{LUAT_ADC_VBAT_RANGE_2_0_RATIO, ADC_VBAT_RESDIV_RATIO_8OVER16, (float)16/8},
{LUAT_ADC_VBAT_RANGE_2_2_RATIO, ADC_VBAT_RESDIV_RATIO_7OVER16, (float)16/7},
{LUAT_ADC_VBAT_RANGE_2_6_RATIO, ADC_VBAT_RESDIV_RATIO_6OVER16, (float)16/6},
{LUAT_ADC_VBAT_RANGE_3_2_RATIO, ADC_VBAT_RESDIV_RATIO_5OVER16, (float)16/5},
{LUAT_ADC_VBAT_RANGE_4_0_RATIO, ADC_VBAT_RESDIV_RATIO_4OVER16, (float)16/4},
{LUAT_ADC_VBAT_RANGE_5_3_RATIO, ADC_VBAT_RESDIV_RATIO_3OVER16, (float)16/3},
{LUAT_ADC_VBAT_RANGE_8_0_RATIO, ADC_VBAT_RESDIV_RATIO_2OVER16, (float)16/2},
{LUAT_ADC_VBAT_RANGE_16_0_RATIO, ADC_VBAT_RESDIV_RATIO_1OVER16, (float)16/1},
};
size_t i = 0;
for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
{
if(map[i].range == range)
{
if (resdiv)
{
*resdiv = map[i].resdiv;
}
if (ratio)
{
*ratio = map[i].ratio;
}
return 0;
}
}
return 1;
}
static void adc0_cb(uint32_t result) {
aio3ChannelResult = result;
adc_state[0] = 1;
}
static void adc1_cb(uint32_t result) {
aio4ChannelResult = result;
adc_state[1] = 1;
}
static void adc_vbat_cb(uint32_t result) {
vbatChannelResult = result;
adc_state[2] = 1;
}
static void adc_temp_cb(uint32_t result) {
thermalChannelResult = result;
adc_state[3] = 1;
}
static volatile uint8_t adc_init = 1;
int luat_adc_open(int id, void* ptr) {
AdcConfig_t adcConfig;
if (!adc_exist(id))
return -1;
ADC_getDefaultConfig(&adcConfig);
if (adc_init){
trimAdcSetGolbalVar();
adc_init = 0;
}
AdcAioResDiv_e resdiv;
if (LUAT_ADC_CH_CPU == id)
{
adc_range_to_resdiv(id, adc_range[2], &resdiv, NULL);
}
else if (LUAT_ADC_CH_VBAT == id)
{
adc_range_to_resdiv(id, adc_range[3], &resdiv, NULL);
}
else
{
adc_range_to_resdiv(id, adc_range[id], &resdiv, NULL);
}
switch (id)
{
case 0:
adcConfig.channelConfig.aioResDiv = resdiv;
ADC_channelInit(ADC_CHANNEL_AIO3, ADC_USER_APP, &adcConfig, adc0_cb);
adc_state[0] = 0;
break;
case 1:
adcConfig.channelConfig.aioResDiv = resdiv;
ADC_channelInit(ADC_CHANNEL_AIO4, ADC_USER_APP, &adcConfig, adc1_cb);
adc_state[1] = 0;
break;
case LUAT_ADC_CH_VBAT: // vbat
adcConfig.channelConfig.vbatResDiv = resdiv;
ADC_channelInit(ADC_CHANNEL_VBAT, ADC_USER_APP, &adcConfig, adc_vbat_cb);
adc_state[2] = 0;
break;
case LUAT_ADC_CH_CPU: // temp
adcConfig.channelConfig.vbatResDiv = resdiv;
ADC_channelInit(ADC_CHANNEL_THERMAL, ADC_USER_APP, NULL, adc_temp_cb);
adc_state[3] = 0;
break;
default:
return -1;
}
return 0;
}
int luat_adc_read(int id, int* val, int* val2) {
if (!adc_exist(id))
return -1;
int t = 1000;
switch (id)
{
case 0:
ADC_startConversion(ADC_CHANNEL_AIO3, ADC_USER_APP);
while(adc_state[0] == 0 && t > 0) {
delay_us(10);
t --;
}; // 1w个循环,通常需要4000个循环
if (adc_state[0] == 0) return -1;
break;
case 1:
ADC_startConversion(ADC_CHANNEL_AIO4, ADC_USER_APP);
while(adc_state[1] == 0 && t > 0) {
delay_us(10);
t --;
}; // 1w个循环,通常需要4000个循环
if (adc_state[1] == 0) return -1;
break;
case LUAT_ADC_CH_VBAT:
ADC_startConversion(ADC_CHANNEL_VBAT, ADC_USER_APP);
while(adc_state[2] == 0 && t > 0) {
delay_us(10);
t --;
}; // 1w个循环,通常需要4000个循环
if (adc_state[2] == 0) return -1;
break;
case LUAT_ADC_CH_CPU:
ADC_startConversion(ADC_CHANNEL_THERMAL, ADC_USER_APP);
while(adc_state[3] == 0 && t > 0) {
delay_us(10);
t --;
}; // 1w个循环,通常需要4000个循环
if (adc_state[3] == 0) return -1;
break;
default:
return -1;
}
float ratio;
if (LUAT_ADC_CH_CPU == id)
{
adc_range_to_resdiv(id, adc_range[2], NULL, &ratio);
}
else if (LUAT_ADC_CH_VBAT == id)
{
adc_range_to_resdiv(id, adc_range[3], NULL, &ratio);
}
else
{
adc_range_to_resdiv(id, adc_range[id], NULL, &ratio);
}
switch (id)
{
case 0:
*val = aio3ChannelResult;
#ifdef __LUATOS__
*val2 = (int)HAL_ADC_CalibrateRawCode(aio3ChannelResult) * ratio /1000;
#else
*val2 = (int)HAL_ADC_CalibrateRawCode(aio3ChannelResult) * ratio ;
#endif
break;
case 1:
*val = aio4ChannelResult;
#ifdef __LUATOS__
*val2 = (int)HAL_ADC_CalibrateRawCode(aio4ChannelResult) * ratio /1000;
#else
*val2 = (int)HAL_ADC_CalibrateRawCode(aio4ChannelResult) * ratio ;
#endif
break;
case LUAT_ADC_CH_VBAT:
*val = vbatChannelResult;
*val2 = (int)HAL_ADC_CalibrateRawCode(vbatChannelResult) * ratio / 1000;
break;
case LUAT_ADC_CH_CPU:
*val = thermalChannelResult;
*val2 = (int)HAL_ADC_ConvertThermalRawCodeToTemperature(thermalChannelResult);
break;
default:
return -1;
}
return 0;
}
int luat_adc_close(int id) {
switch (id)
{
case 0:
ADC_channelDeInit(ADC_CHANNEL_AIO3, ADC_USER_APP);
break;
case 1:
ADC_channelDeInit(ADC_CHANNEL_AIO4, ADC_USER_APP);
break;
case LUAT_ADC_CH_VBAT:
ADC_channelDeInit(ADC_CHANNEL_VBAT, ADC_USER_APP);
break;
case LUAT_ADC_CH_CPU:
ADC_channelDeInit(ADC_CHANNEL_THERMAL, ADC_USER_APP);
break;
default:
return -1;
}
return 0;
}
int luat_adc_global_config(int tp, int val) {
return -1;
}
int luat_adc_ctrl(int id, LUAT_ADC_CTRL_CMD_E cmd, luat_adc_ctrl_param_t param)
{
if (!adc_exist(id))
{
return -1;
}
switch (cmd)
{
case LUAT_ADC_SET_GLOBAL_RANGE:
if (LUAT_ADC_CH_CPU == id)
{
adc_range[2] = param.range;
}
else if (LUAT_ADC_CH_VBAT == id)
{
adc_range[3] = param.range;
}
else
{
adc_range[id] = param.range;
}
break;
default:
return -1;
break;
}
return 0;
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#include "rng.h"
#include "luat_crypto.h"
#include "mbedtls/md5.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/base64.h"
#include "mbedtls/des.h"
#include "mbedtls/aes.h"
#include "mbedtls/rsa.h"
void luat_crypto_md5( unsigned char *input, int ilen, unsigned char output[16] )
{
mbedtls_md5(input, ilen, output);
}
/**
* @brief BASE64加密
* @param dst buffer
* @param dlen buffer长度
* @param olen 写入的字节数
* @param src 加密密钥
* @param slen 加密密钥长度
* @return 0成功
*/
int luat_crypto_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
{
mbedtls_base64_encode(dst, dlen, olen, src, slen);
}
/**
* @brief BASE64解密
* @param dst buffer
* @param dlen buffer长度
* @param olen 写入的字节数
* @param src 密钥
* @param slen 密钥长度
* @return 0成功
*/
int luat_crypto_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
{
mbedtls_base64_decode(dst, dlen, olen, src, slen);
}
/**
* @brief 进行SHA1校验
* @param input 输入的数据
* @param ilen 输入的数据长度
* @param output 输出的SHA1检验值
*/
void luat_crypto_sha1(const unsigned char *input, size_t ilen, unsigned char output[20])
{
mbedtls_sha1(input, ilen, output);
}
/**
* @brief 进行SHA256校验
* @param input 输入的数据
* @param ilen 输入的数据长度
* @param output 输出的SHA1检验值
* @param is_224 是否是224校验
*/
void luat_crypto_sha256(const unsigned char *input, size_t ilen, unsigned char output[20], int is_224)
{
mbedtls_sha256(input, ilen, output, is_224);
}
int luat_crypto_trng(char* buff, size_t len) {
uint8_t tmp[24];
for (size_t i = 0; i < len; i+=24)
{
rngGenRandom(tmp);
memcpy(buff + i, tmp, len - i > 24 ? 24 : len - i);
}
return 0;
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_debug.h"
#include "common_api.h"
#include "plat_config.h"
#include "reset.h"
extern void soc_assert(const char *fun_name, uint32_t line_no, const char *fmt, va_list ap);
extern void soc_vsprintf(uint8_t no_print, const char *fmt, va_list ap);
void luat_debug_set_fault_mode(LUAT_DEBUG_FAULT_MODE_E mode)
{
BSP_SetPlatConfigItemValue(PLAT_CONFIG_ITEM_FAULT_ACTION, (LUAT_DEBUG_FAULT_RESET == mode)?4:0);
if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_FAULT_ACTION) == EXCEP_OPTION_SILENT_RESET)
ResetLockupCfg(true, true);
else
ResetLockupCfg(false, false);
}
void luat_debug_assert(const char *fun_name, unsigned int line_no, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
soc_assert(fun_name, line_no, fmt, ap);
va_end(ap);
}
void luat_debug_print(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
soc_vsprintf(0, fmt, ap);
va_end(ap);
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "luat_base.h"
#include "luat_rtos.h"
#include "luat_mem.h"
#include "luat_debug.h"
#include "stdio.h"
#include "stdlib.h"
#include "flash_rt.h"
int luat_flash_read(char* buff, size_t addr, size_t len) {
int ret = 0;
if (len == 0)
return 0;
ret = BSP_QSPI_Read_Safe((uint8_t *)buff, addr, len);
return ret == 0 ? len : -1;
}
int luat_flash_write(char* buff, size_t addr, size_t len) {
int ret = 0;
if (len == 0)
return 0;
// 注意, BSP_QSPI_Write_Safe 的buf不能是flash上的常量数据
// 写入flash时XIP会关闭, 导致buf值肯定读不到
// 下面的各种判断, 就是把常量数据拷贝到ram, 然后写入
uint8_t tmp_small[128];
uint8_t *tmp = NULL;
uint32_t buff_addr = (uint32_t)buff;
if (len <= 128) {
// 对于较小的数据, 直接在栈内存里拷贝即可,不必判断
memcpy(tmp_small, buff, len);
ret = BSP_QSPI_Write_Safe((uint8_t *)tmp_small, addr, len);
}
else if (buff_addr >= 0x00400000 && buff_addr <= 0x00500000) {
// 数据已经处于ram, 可以直接写入
ret = BSP_QSPI_Write_Safe((uint8_t *)buff, addr, len);
}
else {
// 超过128字节的常量数据, 应该是不存在的吧, 下面的逻辑主要是防御代码.
tmp = malloc(len);
if (tmp == NULL) {
LUAT_DEBUG_PRINT("out of memory when malloc flash write buff");
return -1;
}
memcpy(tmp, buff, len);
ret = BSP_QSPI_Write_Safe((uint8_t *)tmp, addr, len);
free(tmp);
}
return ret == 0 ? len : -1;
}
int luat_flash_erase(size_t addr, size_t len) {
int ret = 0;
ret = BSP_QSPI_Erase_Safe(addr, len);
return ret == 0 ? 0 : -1;
}

View File

@@ -0,0 +1,497 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "luat_base.h"
#include "luat_fs.h"
#include "osasys.h"
#include "lfs_port.h"
#include "luat_rtos.h"
#include "luat_debug.h"
#ifdef __LUATOS__
#include "luat_malloc.h"
#define LUAT_LOG_TAG "fs"
#include "luat_log.h"
#include "mem_map.h"
#else
#include "luat_mem.h"
#endif
static inline const char* check_path(const char* path) {
// if (path == NULL || strlen(path) < 1)
// return NULL;
// const char* dst = path;
// if (dst[0] == '/')
// dst = path + 1;
return path;
}
static inline int is_file(const char* path) {
if (path == NULL || strlen(path) < 1 || path[strlen(path) - 1] == '/')
return 0;
return 1;
}
// #ifdef LUAT_USE_FS_VFS
// #if 1
FILE* luat_vfs_ec618_fopen(__attribute__((unused)) void* userdata, const char *filename, const char *mode) {
int flag = 0;
const char* dst = check_path(filename);
if (dst == NULL || is_file(dst) == 0)
return NULL;
//LLOGD("luat_fs_fopen %s %s", filename, mode);
lfs_file_t *file = (lfs_file_t*)luat_heap_malloc(sizeof(lfs_file_t));
if (NULL == file) {
//LLOGE("out of memory when open file");
return NULL;
}
/*
"r": 读模式(默认);
"w": 写模式;
"a": 追加模式;
"r+": 更新模式,所有之前的数据都保留;
"w+": 更新模式,所有之前的数据都删除;
"a+": 追加更新模式,所有之前的数据都保留,只允许在文件尾部做写入。
*/
if (!strcmp("r+", mode) || !strcmp("r+b", mode) || !strcmp("rb+", mode)) {
flag = LFS_O_RDWR | LFS_O_CREAT;
}
else if(!strcmp("w+", mode) || !strcmp("w+b", mode) || !strcmp("wb+", mode)) {
flag = LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC;
}
else if(!strcmp("a+", mode) || !strcmp("a+b", mode) || !strcmp("ab+", mode)) {
flag = LFS_O_RDWR | LFS_O_APPEND | LFS_O_CREAT;
}
else if(!strcmp("w", mode) || !strcmp("wb", mode)) {
flag = LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC;
}
else if(!strcmp("r", mode) || !strcmp("rb", mode)) {
flag = LFS_O_RDONLY;
}
else if(!strcmp("a", mode) || !strcmp("ab", mode)) {
flag = LFS_O_WRONLY | LFS_O_APPEND | LFS_O_CREAT;
}
else {
//LLOGW("bad file open mode %s, fallback to 'r'", mode);
flag = LFS_O_RDONLY;
}
int ret = LFS_fileOpen(file, dst, flag);
//LLOGD("luat_fs_fopen %s %s ret %d", filename, mode, ret);
if (ret == LFS_ERR_OK) {
return (FILE*)file;
}
luat_heap_free(file);
return NULL;
}
int luat_vfs_ec618_getc(__attribute__((unused))void* userdata, FILE* stream) {
char buff[1];
buff[0] = 0;
int ret = LFS_fileRead((lfs_file_t*)stream, buff, 1);
if (ret == 1)
return buff[0];
return -1;
}
int luat_vfs_ec618_fseek(__attribute__((unused))void* userdata, FILE* stream, long int offset, int origin) {
//DBG("luat_fs_fseek fd=%p offset=%ld ori=%ld", stream, offset, origin);
return LFS_fileSeek((lfs_file_t*)stream, offset, origin);
}
int luat_vfs_ec618_ftell(__attribute__((unused))void* userdata, FILE* stream) {
//DBG("luat_fs_ftell fd=%ld", stream);
return LFS_fileTell((lfs_file_t *)stream);
}
int luat_vfs_ec618_fclose(__attribute__((unused))void* userdata, FILE* stream) {
if (stream == NULL)
return 0;
LFS_fileClose((lfs_file_t *)stream);
free(stream);
return 0;
}
int luat_vfs_ec618_feof(__attribute__((unused))void* userdata, FILE* stream) {
return LFS_fileTell((lfs_file_t *)stream) == LFS_fileSize((lfs_file_t *)stream) ? 1 : 0;
}
int luat_vfs_ec618_ferror(__attribute__((unused))void* userdata, __attribute__((unused))FILE *stream) {
return 0;
}
size_t luat_vfs_ec618_fread(__attribute__((unused))void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
lfs_ssize_t ret = LFS_fileRead((lfs_file_t*)stream, ptr, size * nmemb);
//DBG("luat_fs_fread fd=%p size=%ld nmemb=%ld ret=%ld", stream, size, nmemb, t);
//DBG("luat_fs_fread data[0-7] %p %X %X %X %X %X %X %X %X", data, *(data), *(data+1), *(data+2), *(data+3), *(data+4), *(data+5), *(data+6), *(data+7));
if (ret < 0)
return 0;
return ret;
}
size_t luat_vfs_ec618_fwrite(__attribute__((unused))void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
//DBG("luat_fs_fwrite fd=%p size=%ld nmemb=%ld", stream, size, nmemb);
lfs_ssize_t ret = LFS_fileWrite((lfs_file_t*)stream, ptr, size * nmemb);
if (ret < 0)
return 0;
return ret;
}
int luat_vfs_ec618_remove(__attribute__((unused))void* userdata, const char *filename) {
const char* dst = check_path(filename);
if (dst == NULL)
return 0;
return LFS_remove(dst);
}
int luat_vfs_ec618_rename(__attribute__((unused))void* userdata, const char *old_filename, const char *new_filename) {
const char* src = check_path(old_filename);
if (src == NULL)
return 0;
const char* dst = check_path(new_filename);
if (dst == NULL)
return 0;
return LFS_rename(src, dst);
}
int luat_vfs_ec618_fexist(__attribute__((unused))void* userdata, const char *filename) {
const char* dst = check_path(filename);
if (dst == NULL)
return 0;
lfs_file_t file = {0};
int ret = LFS_fileOpen(&file, dst, LFS_O_RDONLY);
if (ret == LFS_ERR_OK) {
LFS_fileClose(&file);
return 1;
}
return 0;
}
size_t luat_vfs_ec618_fsize(__attribute__((unused))void* userdata, const char *filename) {
const char* dst = check_path(filename);
if (dst == NULL)
return 0;
lfs_file_t file = {0};
int ret = LFS_fileOpen(&file, dst, LFS_O_RDONLY);
if (ret == LFS_ERR_OK) {
size_t sz = LFS_fileSize(&file);
LFS_fileClose(&file);
return sz;
}
return 0;
}
int luat_vfs_ec618_truncate(__attribute__((unused))void* userdata, const char* filename, size_t len) {
const char* dst = check_path(filename);
if (dst == NULL)
return -1;
lfs_file_t file = {0};
int ret = LFS_fileOpen(&file, dst, LFS_O_RDWR);
if (ret != LFS_ERR_OK) {
return -2;
}
ret = LFS_fileTruncate(&file, len);
LFS_fileClose(&file);
return ret;
}
int luat_vfs_ec618_mkfs(__attribute__((unused))void* userdata, __attribute__((unused))luat_fs_conf_t *conf) {
//DBG("not support yet : mkfs");
return -1;
}
int luat_vfs_ec618_mount(__attribute__((unused))void** userdata, __attribute__((unused))luat_fs_conf_t *conf) {
//DBG("not support yet : mount");
return 0;
}
int luat_vfs_ec618_umount(__attribute__((unused))void* userdata, __attribute__((unused))luat_fs_conf_t *conf) {
//DBG("not support yet : umount");
return 0;
}
int LFS_mkdir(const char* dir);
int luat_vfs_ec618_mkdir(__attribute__((unused))void* userdata, __attribute__((unused))char const* _DirName) {
const char* dir = check_path(_DirName);
char buff[64] = {0};
//LUAT_DEBUG_PRINT("mkdir %s %s", dir, _DirName);
if (dir == NULL)
return -1;
size_t len = strlen(dir);
if (strlen(dir) > 63 || strlen(dir) < 2) {
return -2;
}
memcpy(buff, dir, len);
if (buff[len - 1] == '/')
buff[len - 1] = 0x00;
int ret = LFS_mkdir(buff);
//LUAT_DEBUG_PRINT("mkdir %s %s %d", dir, _DirName, ret);
return ret;
}
int luat_vfs_ec618_rmdir(__attribute__((unused))void* userdata, __attribute__((unused))char const* _DirName) {
const char* dir = check_path(_DirName);
if (dir == NULL)
return -1;
return LFS_remove(dir);
}
int luat_vfs_ec618_lsdir(__attribute__((unused))void* userdata, char const* dir_name, luat_fs_dirent_t* ents, size_t offset, size_t len) {
int ret = 0;
size_t num = 0;
lfs_dir_t *dir = NULL;
struct lfs_info info = {0};
const char* dirpath = check_path(dir_name);
// if (fs->filecount > offset) {
// if (offset + len > fs->filecount)
// len = fs->filecount - offset;
dir = luat_heap_malloc(sizeof(lfs_dir_t));
if (dir == NULL) {
// LLOGE("out of memory when lsdir");
return 0;
}
ret = LFS_dirOpen(dir, dirpath); // 固定值, 因为不支持文件夹
if (ret < 0) {
luat_heap_free(dir);
// LLOGE("no such dir %s _DirName");
return 0;
}
// TODO 使用seek/tell组合更快更省
for (size_t i = 0; i < offset; i++)
{
ret = LFS_dirRead(dir, &info);
if (ret <= 0) {
LFS_dirClose(dir);
luat_heap_free(dir);
return 0;
}
}
while (num < len)
{
ret = LFS_dirRead(dir, &info);
if (ret < 0) {
LFS_dirClose(dir);
luat_heap_free(dir);
return 0;
}
if (ret == 0) {
break;
}
if (info.type == 2 && (memcmp(info.name, ".", 2) !=0 ||memcmp(info.name, "..", 3)!=0))
continue;
ents[num].d_type = info.type - 1; // lfs file =1, dir=2
strcpy(ents[num].d_name, info.name);
num++;
}
LFS_dirClose(dir);
luat_heap_free(dir);
return num;
// }
// return 0;
}
int luat_vfs_ec618_info(__attribute__((unused))void* userdata, __attribute__((unused))const char* path, luat_fs_info_t *conf) {
lfs_status_t status = {0};
int ret = LFS_statfs(&status);
if (ret == LFS_ERR_OK) {
conf->total_block = status.total_block;
conf->block_used = status.block_used;
conf->block_size = status.block_size;
conf->type = 1; // 片上FLASH
memcpy(conf->filesystem, "lfs", 3);
conf->filesystem[4] = 0;
return 0;
}
// else {
// DBG("LFS_Statfs return %d", ret);
// }
return -1;
}
#ifdef LUAT_USE_FS_VFS
#define T(name) .name = luat_vfs_ec618_##name
const struct luat_vfs_filesystem vfs_fs_ec618 = {
.name = "ec618",
.opts = {
T(mkfs),
T(mount),
T(umount),
T(mkdir),
T(rmdir),
T(remove),
T(rename),
T(fsize),
T(fexist),
T(info),
T(lsdir)
},
.fopts = {
T(fopen),
T(getc),
T(fseek),
T(ftell),
T(fclose),
T(feof),
T(ferror),
T(fread),
T(fwrite)
}
};
#ifdef __LUATOS__
extern const struct luat_vfs_filesystem vfs_fs_lfs2;
extern const struct luat_vfs_filesystem vfs_fs_luadb;
void luat_lv_fs_init(void);
void lv_split_jpeg_init(void);
void lv_bmp_init(void);
void lv_png_init(void);
#endif
int luat_fs_init(void) {
luat_vfs_reg(&vfs_fs_ec618);
#ifdef __LUATOS__
luat_vfs_reg(&vfs_fs_lfs2);
luat_vfs_reg(&vfs_fs_luadb);
#endif
luat_fs_conf_t conf = {
.busname = "",
.type = "ec618",
.filesystem = "ec618",
.mount_point = ""
};
luat_fs_mount(&conf);
#ifdef __LUATOS__
// 以下为临时配置, 从APP区的末端,切出128k作为临时脚本区80K作为OTA区
#define LUADB_ADDR ((uint32_t)LUA_SCRIPT_ADDR | AP_FLASH_XIP_ADDR)
//DBG("luadb tmp addr %p", LUADB_ADDR);
luat_fs_conf_t conf2 = {
.busname = (char*)(const char*)LUADB_ADDR,
.type = "luadb",
.filesystem = "luadb",
.mount_point = "/luadb/",
};
luat_fs_mount(&conf2);
#ifdef LUAT_USE_LVGL
luat_lv_fs_init();
// lv_bmp_init();
// lv_png_init();
lv_split_jpeg_init();
#endif
#endif
return 0;
}
#else
FILE* luat_fs_fopen(const char *filename, const char *mode) {
return luat_vfs_ec618_fopen(NULL, filename, mode);
}
int luat_fs_getc(FILE* stream) {
return luat_vfs_ec618_getc(NULL, stream);
}
int luat_fs_fseek(FILE* stream, long int offset, int origin) {
return luat_vfs_ec618_fseek(NULL, stream, offset, origin);
}
int luat_fs_ftell(FILE* stream) {
return luat_vfs_ec618_ftell(NULL, stream);
}
int luat_fs_fclose(FILE* stream) {
return luat_vfs_ec618_fclose(NULL, stream);
}
int luat_fs_feof(FILE* stream) {
return luat_vfs_ec618_feof(NULL, stream);
}
int luat_fs_ferror(FILE *stream) {
return luat_vfs_ec618_ferror(NULL, stream);
}
size_t luat_fs_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
return luat_vfs_ec618_fread(NULL, ptr, size, nmemb, stream);
}
size_t luat_fs_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
return luat_vfs_ec618_fwrite(NULL, ptr, size, nmemb, stream);
}
int luat_fs_remove(const char *filename) {
return luat_vfs_ec618_remove(NULL, filename);
}
int luat_fs_rename(const char *old_filename, const char *new_filename) {
return luat_vfs_ec618_rename(NULL, old_filename, new_filename);
}
size_t luat_fs_fsize(const char *filename) {
return luat_vfs_ec618_fsize(NULL, filename);
}
int luat_fs_fexist(const char *filename) {
return luat_vfs_ec618_fexist(NULL, filename);
}
// int luat_fs_ftruncate(FILE* fp, size_t len) {
// }
int luat_fs_truncate(const char* filename, size_t len) {
return luat_vfs_ec618_truncate(NULL, filename, len);
}
// int luat_fs_readline(char * buf, int bufsize, FILE * stream);
// 文件夹相关的API
int luat_fs_mkdir(char const* dir) {
return luat_vfs_ec618_mkdir(NULL, dir);
}
int luat_fs_rmdir(char const* dir) {
return luat_vfs_ec618_rmdir(NULL, dir);
}
int luat_fs_lsdir(char const* dir, luat_fs_dirent_t* ents, size_t offset, size_t len) {
return luat_vfs_ec618_lsdir(NULL, dir, ents, offset, len);
}
int luat_fs_init(void) {
return 0;
}
int luat_fs_info(const char* path, luat_fs_info_t *info){
return luat_vfs_ec618_info(NULL, path, info);
}
extern int lfs_ready;
int luat_fs_ready(void) {
return lfs_ready;
}
#endif

View File

@@ -0,0 +1,437 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "luat_gpio.h"
#include "driver_gpio.h"
#include "slpman.h"
#include "FreeRTOS.h"
#include "pwrkey.h"
typedef void(* pwrKeyIsrCb)(void);
extern pwrKeyIsrCb pwrKeyIsrCallback;
__attribute__((weak)) int luat_gpio_irq_default(int pin, void* args)
{
return 0;
}
static int luat_gpio_irq_callback(void *ptr, void *pParam)
{
int pin = (int)ptr;
luat_gpio_irq_default(pin, (void*)luat_gpio_get(pin));
return 0;
}
static void luat_gpio_pwrkey_irq_callback(void)
{
luat_gpio_irq_default(HAL_WAKEUP_PWRKEY, (void*)pwrKeyGetPinLevel());
return ;
}
void luat_gpio_set_default_cfg(luat_gpio_cfg_t* gpio)
{
memset(gpio, 0, sizeof(luat_gpio_cfg_t));
}
int luat_gpio_open(luat_gpio_cfg_t* gpio)
{
#ifdef __LUATOS__
if (((uint32_t)(gpio->pin)) >= HAL_GPIO_QTY) return -1;
#else
if (((uint32_t)(gpio->pin)) >= HAL_WAKEUP_PWRKEY) return -1;
#endif
GPIO_GlobalInit(NULL);
#ifdef __LUATOS__
if (HAL_WAKEUP_PWRKEY == gpio->pin)
{
if (gpio->mode != LUAT_GPIO_IRQ)
{
return -1;
}
pwrKeyIsrCallback = luat_gpio_pwrkey_irq_callback;
pwrKeyHwInit((LUAT_GPIO_PULLUP == gpio->pull)?1:0);
NVIC_EnableIRQ(PwrkeyWakeup_IRQn);
return 0;
}
#endif
if (gpio->pin >= HAL_GPIO_MAX)
{
APmuWakeupPadSettings_t padConfig = {0};
if (LUAT_GPIO_OUTPUT == gpio->mode) return -1;
uint8_t pad_id = gpio->pin - HAL_WAKEUP_0;
switch (gpio->pull)
{
case LUAT_GPIO_PULLUP:
padConfig.pullUpEn = 1;
break;
case LUAT_GPIO_PULLDOWN:
padConfig.pullDownEn = 1;
break;
default:
break;
}
if (LUAT_GPIO_IRQ == gpio->mode)
{
if (gpio->irq_cb) {
GPIO_ExtiSetCB(gpio->pin, gpio->irq_cb, gpio->irq_args);
}
else
{
GPIO_ExtiSetCB(gpio->pin, luat_gpio_irq_callback, gpio->irq_args);
}
switch (gpio->irq_type)
{
case LUAT_GPIO_RISING_IRQ:
padConfig.posEdgeEn = 1;
break;
case LUAT_GPIO_FALLING_IRQ:
padConfig.negEdgeEn = 1;
break;
case LUAT_GPIO_BOTH_IRQ:
padConfig.posEdgeEn = 1;
padConfig.negEdgeEn = 1;
break;
default:
return -1;
break;
}
apmuSetWakeupPadCfg(pad_id, true, &padConfig);
NVIC_EnableIRQ(pad_id);
}
else
{
NVIC_DisableIRQ(pad_id);
NVIC_ClearPendingIRQ(pad_id);
apmuSetWakeupPadCfg(pad_id, false, &padConfig);
GPIO_ExtiSetCB(gpio->pin, NULL, gpio->irq_args);
}
return 0;
}
uint8_t is_pull;
uint8_t is_pullup;
uint8_t is_input = (LUAT_GPIO_OUTPUT == gpio->mode)?0:1;
switch (gpio->pull)
{
case LUAT_GPIO_PULLUP:
is_pull = 1;
is_pullup = 1;
break;
case LUAT_GPIO_PULLDOWN:
is_pull = 1;
is_pullup = 0;
break;
default:
is_pull = 0;
is_pullup = 0;
break;
}
GPIO_Config(gpio->pin, is_input, gpio->output_level);
GPIO_PullConfig(GPIO_ToPadEC618(gpio->pin, gpio->alt_fun), is_pull, is_pullup);
if (LUAT_GPIO_IRQ == gpio->mode)
{
if (gpio->irq_cb) {
GPIO_ExtiSetCB(gpio->pin, gpio->irq_cb, gpio->irq_args);
}
else
{
GPIO_ExtiSetCB(gpio->pin, luat_gpio_irq_callback, gpio->irq_args);
}
switch (gpio->irq_type)
{
case LUAT_GPIO_RISING_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,1,0);
break;
case LUAT_GPIO_FALLING_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,0,1);
break;
case LUAT_GPIO_BOTH_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,1,1);
break;
case LUAT_GPIO_HIGH_IRQ:
GPIO_ExtiConfig(gpio->pin, 1,1,0);
break;
case LUAT_GPIO_LOW_IRQ:
GPIO_ExtiConfig(gpio->pin, 1,0,1);
break;
default:
GPIO_ExtiConfig(gpio->pin, 0,0,0);
break;
}
}
else
{
GPIO_ExtiConfig(gpio->pin, 0,0,0);
GPIO_ExtiSetCB(gpio->pin, NULL, NULL);
}
GPIO_IomuxEC618(GPIO_ToPadEC618(gpio->pin, gpio->alt_fun), gpio->alt_fun, 0, 0);
return 0;
}
int luat_gpio_setup(luat_gpio_t *gpio){
if (((uint32_t)(gpio->pin)) >= HAL_GPIO_QTY) return -1;
GPIO_GlobalInit(NULL);
#ifdef __LUATOS__
if (HAL_WAKEUP_PWRKEY == gpio->pin)
{
if (gpio->mode != LUAT_GPIO_IRQ)
{
return -1;
}
pwrKeyIsrCallback = luat_gpio_pwrkey_irq_callback;
pwrKeyHwInit((LUAT_GPIO_PULLUP == gpio->pull)?1:0);
NVIC_EnableIRQ(PwrkeyWakeup_IRQn);
return 0;
}
#endif
if (gpio->pin >= HAL_GPIO_MAX)
{
APmuWakeupPadSettings_t padConfig = {0};
if (LUAT_GPIO_OUTPUT == gpio->mode) return -1;
uint8_t pad_id = gpio->pin - HAL_WAKEUP_0;
switch (gpio->pull)
{
case LUAT_GPIO_PULLUP:
padConfig.pullUpEn = 1;
break;
case LUAT_GPIO_PULLDOWN:
padConfig.pullDownEn = 1;
break;
default:
break;
}
if (LUAT_GPIO_IRQ == gpio->mode)
{
if (gpio->irq_cb) {
GPIO_ExtiSetCB(gpio->pin, gpio->irq_cb, gpio->irq_args);
}
else
{
GPIO_ExtiSetCB(gpio->pin, luat_gpio_irq_callback, gpio->irq_args);
}
switch (gpio->irq)
{
case LUAT_GPIO_RISING_IRQ:
padConfig.posEdgeEn = 1;
break;
case LUAT_GPIO_FALLING_IRQ:
padConfig.negEdgeEn = 1;
break;
case LUAT_GPIO_BOTH_IRQ:
padConfig.posEdgeEn = 1;
padConfig.negEdgeEn = 1;
break;
default:
return -1;
break;
}
apmuSetWakeupPadCfg(pad_id, true, &padConfig);
NVIC_EnableIRQ(pad_id);
}
else
{
NVIC_DisableIRQ(pad_id);
NVIC_ClearPendingIRQ(pad_id);
apmuSetWakeupPadCfg(pad_id, false, &padConfig);
GPIO_ExtiSetCB(gpio->pin, NULL, gpio->irq_args);
}
return 0;
}
uint8_t is_pull;
uint8_t is_pullup;
uint8_t is_input = (LUAT_GPIO_OUTPUT == gpio->mode)?0:1;
switch (gpio->pull)
{
case LUAT_GPIO_PULLUP:
is_pull = 1;
is_pullup = 1;
break;
case LUAT_GPIO_PULLDOWN:
is_pull = 1;
is_pullup = 0;
break;
default:
is_pull = 0;
is_pullup = 0;
break;
}
GPIO_Config(gpio->pin, is_input, is_pullup);
GPIO_PullConfig(GPIO_ToPadEC618(gpio->pin, 0), is_pull, is_pullup);
if (LUAT_GPIO_IRQ == gpio->mode)
{
if (gpio->irq_cb) {
GPIO_ExtiSetCB(gpio->pin, gpio->irq_cb, gpio->irq_args);
}
else
{
GPIO_ExtiSetCB(gpio->pin, luat_gpio_irq_callback, gpio->irq_args);
}
switch (gpio->irq)
{
case LUAT_GPIO_RISING_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,1,0);
break;
case LUAT_GPIO_FALLING_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,0,1);
break;
case LUAT_GPIO_BOTH_IRQ:
GPIO_ExtiConfig(gpio->pin, 0,1,1);
break;
case LUAT_GPIO_HIGH_IRQ:
GPIO_ExtiConfig(gpio->pin, 1,1,0);
break;
case LUAT_GPIO_LOW_IRQ:
GPIO_ExtiConfig(gpio->pin, 1,0,1);
break;
default:
GPIO_ExtiConfig(gpio->pin, 0,0,0);
break;
}
}
else
{
GPIO_ExtiConfig(gpio->pin, 0,0,0);
GPIO_ExtiSetCB(gpio->pin, NULL, NULL);
}
GPIO_IomuxEC618(GPIO_ToPadEC618(gpio->pin, 0), 0, 0, 0);
return 0;
}
int luat_gpio_set(int pin, int level){
if (((uint32_t)(pin)) >= HAL_GPIO_MAX) return -1;
GPIO_Output(pin, level);
return 0;
}
int luat_gpio_get(int pin){
if (((uint32_t)(pin)) >= HAL_GPIO_QTY) return 0;
uint8_t re;
if (HAL_WAKEUP_PWRKEY == pin)
{
return pwrKeyGetPinLevel();
}
if (pin >= HAL_GPIO_MAX)
{
pin -= HAL_WAKEUP_0;
re = slpManGetWakeupPinValue() & (1 << pin);
}
else
{
re = GPIO_Input(pin);
}
return re?1:0;
}
void luat_gpio_close(int pin){
#ifdef __LUATOS__
if (pin >= HAL_GPIO_QTY) return ;
if (HAL_WAKEUP_PWRKEY == pin)
{
NVIC_DisableIRQ(PwrkeyWakeup_IRQn);
NVIC_ClearPendingIRQ(PwrkeyWakeup_IRQn);
pwrKeyHwDeinit(0);
pwrKeyIsrCallback = NULL;
return;
}
#else
if (pin >= HAL_WAKEUP_PWRKEY) return ;
#endif
if (pin >= HAL_GPIO_MAX)
{
GPIO_WakeupPadConfig(pin, 0, 0, 0, 0);
}
GPIO_ExtiSetCB(pin, NULL, 0);
GPIO_ExtiConfig(pin, 0,0,0);
return ;
}
int luat_gpio_set_irq_cb(int pin, luat_gpio_irq_cb cb, void* args)
{
#ifdef __LUATOS__
if (pin >= HAL_GPIO_QTY) return -1;
if (HAL_WAKEUP_PWRKEY == pin)
{
pwrKeyIsrCallback = cb;
return 0;
}
GPIO_ExtiSetCB(pin, cb, args);
#else
if (pin >= HAL_WAKEUP_PWRKEY) return -1;
GPIO_ExtiSetCB(pin, cb, args);
#endif
return 0;
}
void luat_gpio_pulse(int pin, uint8_t *level, uint16_t len, uint16_t delay_ns)
{
GPIO_OutPulse(pin, level, len, delay_ns);
}
int luat_gpio_ctrl(int pin, LUAT_GPIO_CTRL_CMD_E cmd, int param)
{
if (pin > (HAL_GPIO_MAX + 1)) return -1;
uint8_t alt_fun = (param >> 28);
switch(cmd)
{
case LUAT_GPIO_CMD_SET_PULL_MODE:
switch(param)
{
case LUAT_GPIO_PULLUP:
GPIO_Config(GPIO_ToPadEC618(pin, alt_fun), 1, 1);
break;
case LUAT_GPIO_PULLDOWN:
GPIO_Config(GPIO_ToPadEC618(pin, alt_fun), 1, 0);
break;
default:
GPIO_Config(GPIO_ToPadEC618(pin, alt_fun), 0, 0);
break;
}
break;
case LUAT_GPIO_CMD_SET_IRQ_MODE:
switch(param)
{
case LUAT_GPIO_RISING_IRQ:
GPIO_ExtiConfig(pin, 0,1,0);
break;
case LUAT_GPIO_FALLING_IRQ:
GPIO_ExtiConfig(pin, 0,0,1);
break;
case LUAT_GPIO_BOTH_IRQ:
GPIO_ExtiConfig(pin, 0,1,1);
break;
case LUAT_GPIO_HIGH_IRQ:
GPIO_ExtiConfig(pin, 1,1,0);
break;
case LUAT_GPIO_LOW_IRQ:
GPIO_ExtiConfig(pin, 1,0,1);
break;
default:
GPIO_ExtiConfig(pin, 0,0,0);
break;
}
break;
default:
return -1;
}
return 0;
}

View File

@@ -0,0 +1,318 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if 0
#include "FreeRTOS.h"
#include "luat_i2c.h"
#include "common_api.h"
#include <stdio.h>
#include <string.h>
#include "bsp_custom.h"
#if RTE_I2C0
extern ARM_DRIVER_I2C Driver_I2C0;
static ARM_DRIVER_I2C *i2cDrv0 = &CREATE_SYMBOL(Driver_I2C, 0);
#endif
#if RTE_I2C1
extern ARM_DRIVER_I2C Driver_I2C1;
static ARM_DRIVER_I2C *i2cDrv1 = &CREATE_SYMBOL(Driver_I2C, 1);
#endif
int luat_i2c_exist(int id) {
#if RTE_I2C0
if (id == 0)
return 1;
#endif
#if RTE_I2C1
if (id == 1)
return 1;
#endif
return 0;
}
int luat_i2c_setup(int id, int speed) {
if (!luat_i2c_exist(id)) {
return -1;
}
int ret = 0;
#if RTE_I2C0
if (id==0)
{
ret = i2cDrv0->Initialize(NULL);
if (ret) DBG("i2c0 setup error -- Initialize - %ld", ret);
ret = i2cDrv0->PowerControl(ARM_POWER_FULL);
if (ret) DBG("i2c0 setup error -- PowerControl - %ld", ret);
if (speed == 0)//(100kHz)
ret = i2cDrv0->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
else if (speed == 1)//(400kHz)
ret = i2cDrv0->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
else if (speed == 2)//( 1MHz)
ret = i2cDrv0->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST_PLUS);
else if (speed == 3)//(3.4MHz)
ret = i2cDrv0->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_HIGH);
if (ret) DBG("i2c0 setup error -- Control SPEED - %ld", ret);
ret = i2cDrv0->Control(ARM_I2C_BUS_CLEAR, 0);
if (ret) DBG("i2c0 setup error -- Control CLEAR - %ld", ret);
DBG("i2c0 setup complete");
}
#endif
#if RTE_I2C1
if (id==1)
{
ret = i2cDrv1->Initialize(NULL);
if (ret) DBG("i2c1 setup error -- Initialize - %ld", ret);
ret = i2cDrv1->PowerControl(ARM_POWER_FULL);
if (ret) DBG("i2c1 setup error -- PowerControl - %ld", ret);
if (speed == 0)//(100kHz)
ret = i2cDrv1->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
else if (speed == 1)//(400kHz)
ret = i2cDrv1->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
else if (speed == 2)//( 1MHz)
ret = i2cDrv1->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST_PLUS);
else if (speed == 3)//(3.4MHz)
ret = i2cDrv1->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_HIGH);
if (ret) DBG("i2c1 setup error -- Control SPEED - %ld", ret);
ret = i2cDrv1->Control(ARM_I2C_BUS_CLEAR, 0);
if (ret) DBG("i2c1 setup error -- Control CLEAR - %ld", ret);
DBG("i2c1 setup complete");
}
#endif
return ret;
}
int luat_i2c_close(int id) {
if (!luat_i2c_exist(id)) {
return -1;
}
#if RTE_I2C0
if (id==0){
i2cDrv0->PowerControl(ARM_POWER_OFF);
i2cDrv0->Uninitialize();
}
#endif
#if RTE_I2C1
if (id==1){
i2cDrv1->PowerControl(ARM_POWER_OFF);
i2cDrv1->Uninitialize();
}
#endif
return 0;
}
int luat_i2c_send(int id, int addr, void* buff, size_t len, uint8_t stop) {
if (!luat_i2c_exist(id)) {
return -1;
}
#if RTE_I2C0
if (id==0){
if (stop)
return i2cDrv0->MasterTransmit(addr, buff, len, false);
else
return i2cDrv0->MasterTransmit(addr, buff, len, true);
}
#endif
#if RTE_I2C1
if (id==1){
if (stop)
return i2cDrv1->MasterTransmit(addr, buff, len, false);
else
return i2cDrv1->MasterTransmit(addr, buff, len, true);
}
#endif
}
int luat_i2c_recv(int id, int addr, void* buff, size_t len) {
if (!luat_i2c_exist(id)) {
return -1;
}
#if RTE_I2C0
if (id==0){
return i2cDrv0->MasterReceive(addr, buff, len, false);
}
#endif
#if RTE_I2C1
if (id==1){
return i2cDrv1->MasterReceive(addr, buff, len, false);
}
#endif
}
int luat_i2c_transfer(int id, int addr, uint8_t *reg, size_t reg_len, uint8_t *buff, size_t len)
{
int result;
result = luat_i2c_send(id, addr, reg, reg_len, 0);
if (result != 0) return-1;
return luat_i2c_recv(id, addr, buff, len);
}
#else
#include "luat_i2c.h"
#include "common_api.h"
#include "soc_i2c.h"
#include "driver_gpio.h"
static uint8_t luat_i2c_iomux[I2C_MAX];
int luat_i2c_exist(int id) {
return (id < I2C_MAX);
}
int luat_i2c_set_iomux(int id, uint8_t value)
{
if (!luat_i2c_exist(id)) return -1;
luat_i2c_iomux[id] = value;
}
int luat_i2c_setup(int id, int speed) {
if (speed == 0) {
speed = 100 * 1000; // SLOW
}
else if (speed == 1) {
speed = 400 * 1000; // FAST
}
else if (speed == 2) {
speed = 400 * 1000; // SuperFast
}
if (!luat_i2c_exist(id)) return -1;
if (id)
{
switch(luat_i2c_iomux[id])
{
case 1:
GPIO_IomuxEC618(23, 2, 1, 0);
GPIO_IomuxEC618(24, 2, 1, 0);
break;
default:
GPIO_IomuxEC618(19, 2, 1, 0);
GPIO_IomuxEC618(20, 2, 1, 0);
break;
}
}
else
{
switch(luat_i2c_iomux[id])
{
case 1:
GPIO_IomuxEC618(27, 2, 1, 0);
GPIO_IomuxEC618(28, 2, 1, 0);
break;
case 2:
GPIO_IomuxEC618(16, 2, 1, 0);
GPIO_IomuxEC618(17, 2, 1, 0);
break;
default:
GPIO_IomuxEC618(13, 2, 1, 0);
GPIO_IomuxEC618(14, 2, 1, 0);
break;
}
}
I2C_MasterSetup(id, speed);
return 0;
}
int luat_i2c_close(int id) {
if (!luat_i2c_exist(id)) return -1;
if (id)
{
switch(luat_i2c_iomux[id])
{
case 1:
GPIO_IomuxEC618(23, 0, 1, 0);
GPIO_IomuxEC618(24, 0, 1, 0);
break;
default:
GPIO_IomuxEC618(19, 0, 1, 0);
GPIO_IomuxEC618(20, 0, 1, 0);
break;
}
}
else
{
switch(luat_i2c_iomux[id])
{
case 1:
GPIO_IomuxEC618(27, 0, 1, 0);
GPIO_IomuxEC618(28, 0, 1, 0);
break;
case 2:
GPIO_IomuxEC618(16, 0, 1, 0);
GPIO_IomuxEC618(17, 0, 1, 0);
break;
default:
GPIO_IomuxEC618(13, 0, 1, 0);
GPIO_IomuxEC618(14, 0, 1, 0);
break;
}
}
return 0;
}
int luat_i2c_send(int id, int addr, void* buff, size_t len, uint8_t stop) {
if (!luat_i2c_exist(id)) return -1;
return I2C_BlockWrite(id, addr, (const uint8_t *)buff, len, 25, NULL, NULL);
// I2C_Prepare(id, addr, 1, NULL, NULL);
// I2C_MasterXfer(id, I2C_OP_WRITE, 0, buff, len, 20);
}
int luat_i2c_recv(int id, int addr, void* buff, size_t len) {
if (!luat_i2c_exist(id)) return -1;
return I2C_BlockRead(id, addr, 0, 0, (uint8_t *)buff, len, 25, NULL, NULL);
// I2C_Prepare(id, addr, 1, NULL, NULL);
// I2C_MasterXfer(id, I2C_OP_READ, 0, buff, len, 20);
}
int luat_i2c_transfer(int id, int addr, uint8_t *reg, size_t reg_len, uint8_t *buff, size_t len) {
if (!luat_i2c_exist(id)) return -1;
if (reg && reg_len) {
return I2C_BlockRead(id, addr, reg, reg_len, (uint8_t *)buff, len, 25, NULL, NULL);
} else {
return I2C_BlockWrite(id, addr, (const uint8_t *)buff, len, 25, NULL, NULL);
}
}
extern void I2C_SetNoBlock(uint8_t I2CID);
int luat_i2c_no_block_transfer(int id, int addr, uint8_t is_read, uint8_t *reg, size_t reg_len, uint8_t *buff, size_t len, uint16_t Toms, void *CB, void *pParam) {
if (!luat_i2c_exist(id)) return -1;
int32_t Result;
if (!I2C_WaitResult(id, &Result)) {
return -1;
}
I2C_Prepare(id, addr, 2, CB, pParam);
I2C_SetNoBlock(id);
if (reg && reg_len)
{
I2C_MasterXfer(id, I2C_OP_READ_REG, reg, reg_len, buff, len, Toms);
}
else if (is_read)
{
I2C_MasterXfer(id, I2C_OP_READ, NULL, 0, buff, len, Toms);
}
else
{
I2C_MasterXfer(id, I2C_OP_WRITE, NULL, 0, buff, len, Toms);
}
return 0;
}
#endif

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_i2s_ec618.h"
#include "driver_i2s.h"
#include "driver_gpio.h"
void luat_i2s_init(void)
{
}
void luat_i2s_base_setup(uint8_t bus_id, uint8_t mode, uint8_t frame_size)
{
I2S_BaseConfig(bus_id, mode, frame_size);
switch(bus_id)
{
case I2S_ID0:
GPIO_IomuxEC618(39, 1, 1, 0);
GPIO_IomuxEC618(35, 1, 1, 0);
GPIO_IomuxEC618(36, 1, 1, 0);
GPIO_IomuxEC618(37, 1, 1, 0);
GPIO_IomuxEC618(38, 1, 1, 0);
break;
case I2S_ID1:
GPIO_IomuxEC618(18, 1, 1, 0);
GPIO_IomuxEC618(19, 1, 1, 0);
GPIO_IomuxEC618(20, 1, 1, 0);
GPIO_IomuxEC618(21, 1, 1, 0);
GPIO_IomuxEC618(22, 1, 1, 0);
break;
}
}
int luat_i2s_start(uint8_t bus_id, uint8_t is_play, uint32_t sample, uint8_t channel_num)
{
return I2S_Start(bus_id, is_play, sample, channel_num);
}
void luat_i2s_no_block_tx(uint8_t bus_id, uint8_t* address, uint32_t byte_len, CBFuncEx_t cb, void *param)
{
I2S_Tx(bus_id, address, byte_len, cb, param);
}
void luat_i2s_no_block_rx(uint8_t bus_id, uint32_t byte_len, CBFuncEx_t cb, void *param)
{
I2S_Rx(bus_id,byte_len, cb, param);
}
void luat_i2s_tx_stop(uint8_t bus_id)
{
I2S_TxStop(bus_id);
}
void luat_i2s_rx_stop(uint8_t bus_id)
{
I2S_RxStop(bus_id);
}
void luat_i2s_deinit(uint8_t bus_id)
{
I2S_TxStop(bus_id);
}
void luat_i2s_pause(uint8_t bus_id)
{
I2S_TxPause(bus_id);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#include "luat_iconv.h"
#include "iconv.h"
luat_iconv_t luat_iconv_open (const char *to_code, const char *from_code)
{
return iconv_open(to_code, from_code);
}
size_t luat_iconv_convert (luat_iconv_t cd, char ** inbuf, size_t * in_bytes_left, char ** outbuf, size_t * out_bytes_left)
{
return iconv_convert(cd, inbuf, in_bytes_left, outbuf, out_bytes_left);
}
int luat_iconv_close (luat_iconv_t cd)
{
return iconv_close(cd);
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "luat_base.h"
#include "luat_debug.h"
#include "luat_kv.h"
#include "fal.h"
#include "flashdb.h"
struct fdb_kvdb* luat_kvdb;
size_t luat_kvdb_debug_mode = 0;
int luat_kv_init(void)
{
if (luat_kvdb != NULL) {
return 0;
}
luat_kvdb = malloc(sizeof(struct fdb_kvdb));
if (luat_kvdb == NULL) {
LUAT_DEBUG_PRINT("out of memory when malloc fdb_kvdb");
return -1;
}
memset(luat_kvdb, 0, sizeof(struct fdb_kvdb));
fdb_err_t ret = fdb_kvdb_init(luat_kvdb, "env", "onchip_fdb", NULL, NULL);
LUAT_DEBUG_PRINT("fdb_kvdb_init ret %d", ret);
return ret;
}
int luat_kv_del(const char* key) {
if (luat_kvdb == NULL) {
LUAT_DEBUG_PRINT("luat_kv NEED init!!!");
return -1;
}
return fdb_kv_del(luat_kvdb, key);
}
int luat_kv_set(const char* key, void* data, size_t len) {
if (luat_kvdb == NULL) {
LUAT_DEBUG_PRINT("luat_kv NEED init!!!");
return -1;
}
struct fdb_blob blob = {0};
blob.buf = data;
blob.size = len;
int ret = fdb_kv_set_blob(luat_kvdb, key, &blob);
if (luat_kvdb_debug_mode)
LUAT_DEBUG_PRINT("luat_kv_set %s %p %d %d", key, data, len, ret);
return ret;
}
int luat_kv_get(const char* key, void* data, size_t len) {
if (luat_kvdb == NULL) {
LUAT_DEBUG_PRINT("luat_kv NEED init!!!");
return -1;
}
struct fdb_blob blob = {0};
blob.buf = data;
blob.size = len;
int ret = fdb_kv_get_blob(luat_kvdb, key, &blob);
if (luat_kvdb_debug_mode)
LUAT_DEBUG_PRINT("luat_kv_get %s %p %d %d", key, data, len, ret);
return ret;
}
int luat_kv_clear(void) {
if (luat_kvdb == NULL) {
LUAT_DEBUG_PRINT("luat_kv NEED init!!!");
return -1;
}
fdb_kv_set_default(luat_kvdb);
return 0;
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#include "luat_mcu.h"
long luat_mcu_ticks(void) {
return xTaskGetTickCount();
}
int luat_mcu_set_clk(size_t mhz) {
return 0;
}
int luat_mcu_get_clk(void) {
return 204;
}
// 隐藏API, 头文件里没有
uint8_t QSPI_FLASH_ReadUUID(uint8_t* uuid, uint32_t* validlen);
uint8_t unique_id[16];
uint32_t unique_id_len;
const char* luat_mcu_unique_id(size_t* t) {
if (unique_id[0] == 0) {
QSPI_FLASH_ReadUUID(unique_id, &unique_id_len);
if (unique_id_len == 16) {
for (size_t i = 0; i < 6; i++)
{
if (unique_id[unique_id_len - 1] == 0xFF) {
unique_id_len --;
}
else {
break;
}
}
}
}
*t = unique_id_len;
return (const char*)unique_id;
}
uint32_t luat_mcu_hz(void) {
return 1000;
}
uint64_t luat_mcu_tick64(void) {
return soc_get_poweron_time_tick();
}
int luat_mcu_us_period(void) {
return 26;
}
uint64_t luat_mcu_tick64_ms(void) {
return soc_get_poweron_time_ms();
}
void luat_mcu_set_clk_source(uint8_t source_main, uint8_t source_32k, uint32_t delay) {
// nop
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* mem操作
*
*/
#include <stdlib.h>
void* luat_heap_malloc(size_t len) {
return malloc(len);
}
void luat_heap_free(void* ptr) {
free(ptr);
}
void* luat_heap_realloc(void* ptr, size_t len) {
return realloc(ptr, len);
}
void* luat_heap_calloc(size_t count, size_t _size) {
return calloc(count, _size);
}
size_t xPortGetTotalHeapSize( void );
void luat_meminfo_sys(size_t *total, size_t *used, size_t *max_used) {
*total = xPortGetTotalHeapSize();
*used = *total - xPortGetFreeHeapSize();
*max_used = *total - xPortGetMinimumEverFreeHeapSize();
}

View File

@@ -0,0 +1,516 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_mobile.h"
#include "ps_lib_api.h"
#include "common_api.h"
#include "cmimm.h"
#include "cmidev.h"
#include "cms_api.h"
extern void soc_mobile_event_deregister_handler(void);
extern void soc_mobile_get_imsi(uint8_t *buf);
extern void soc_mobile_get_iccid(uint8_t *buf);
extern void soc_mobile_event_register_handler(void *handle);
extern void soc_mobile_set_period(uint32_t get_cell_period, uint32_t check_sim_period, uint8_t search_cell_time);
extern void soc_mobile_reset_stack(void);
extern void soc_mobile_get_signal(CmiMmCesqInd *info);
extern void soc_mobile_get_cell_info(CmiDevGetBasicCellListInfoInd *info);
extern void soc_mobile_get_sim_id(uint8_t *sim_id, uint8_t *is_auto);
extern void soc_mobile_set_sim_id(uint8_t sim_id);
extern void soc_mobile_sms_event_register_handler(void *handle);
extern uint8_t soc_mobile_get_csq(void);
extern void soc_mobile_search_cell_info_async(uint8_t param);
int soc_mobile_get_default_pdp_part_info(uint8_t *ip_type, uint8_t *apn,uint8_t *apn_len, uint8_t *dns_num, ip_addr_t *dns_ip);
int luat_mobile_get_imei(int sim_id, char* buff, size_t buf_len)
{
char temp[20] = {0};
int result = appGetImeiNumSync(temp);
if (!result)
{
memcpy(buff, temp, (buf_len > sizeof(temp))?sizeof(temp):buf_len);
return (buf_len > sizeof(temp))?sizeof(temp):buf_len;
}
else
{
return -1;
}
}
int luat_mobile_get_sn(char* buff, size_t buf_len)
{
char temp[32] = {0};
int result = appGetSNNumSync(temp);
if (result)
{
memcpy(buff, temp, (buf_len > sizeof(temp))?sizeof(temp):buf_len);
return (buf_len > sizeof(temp))?sizeof(temp):buf_len;
}
else
{
return -1;
}
}
int luat_mobile_set_sn(char* buff, uint8_t buf_len)
{
int result = appSetSNNumSync(buff, buf_len);
return result==1 ? 0 : -1;
}
int luat_mobile_get_muid(char* buff, size_t buf_len)
{
char temp[64] = {0};
int result = soc_get_sn(temp, sizeof(temp));
if (!result)
{
memcpy(buff, temp, (buf_len > sizeof(temp))?sizeof(temp):buf_len);
return (buf_len > sizeof(temp))?sizeof(temp):buf_len;
}
else
{
return -1;
}
}
int luat_mobile_get_iccid(int sim_id, char* buff, size_t buf_len)
{
char temp[24] = {0};
soc_mobile_get_iccid(temp);
if (temp[0])
{
memcpy(buff, temp, (buf_len > sizeof(temp))?sizeof(temp):buf_len);
return (buf_len > sizeof(temp))?sizeof(temp):buf_len;
}
else
{
return -1;
}
}
int luat_mobile_get_imsi(int sim_id, char* buff, size_t buf_len)
{
char temp[20] = {0};
soc_mobile_get_imsi(temp);
if (temp[0])
{
memcpy(buff, temp, (buf_len > sizeof(temp))?sizeof(temp):buf_len);
return (buf_len > sizeof(temp))?sizeof(temp):buf_len;
}
else
{
return -1;
}
}
int luat_mobile_get_sim_id(int *id)
{
uint8_t sim_id, is_auto;
soc_mobile_get_sim_id(&sim_id, &is_auto);
if (sim_id != 0xff)
{
*id = sim_id;
return 0;
}
else
{
return -1;
}
}
int luat_mobile_set_sim_id(int id)
{
if (id > 2)
{
return -1;
}
else
{
soc_mobile_set_sim_id(id);
return 0;
}
}
int luat_mobile_get_apn(int sim_id, int cid, char* buff, size_t buf_len)
{
uint8_t type;
int default_cid = soc_mobile_get_default_pdp_part_info(&type, NULL, NULL, NULL, NULL);
if (cid > 0 && default_cid != cid)
{
return -1;
}
uint8_t apn_len = buf_len;
soc_mobile_get_default_pdp_part_info(&type, buff, &apn_len, NULL, NULL);
return apn_len;
}
int luat_mobile_get_default_apn(int sim_id, char* buff, size_t buf_len)
{
return luat_mobile_get_apn(sim_id, -1, buff, buf_len);
}
int luat_mobile_set_apn(int sim_id, int cid, const char* buff, size_t buf_len)
{
return -1;
}
// 进出飞行模式
int luat_mobile_set_flymode(int index, int mode)
{
return appSetCFUN(!mode);
}
int luat_mobile_get_flymode(int index)
{
uint8_t state;
int result = appGetCFUN(&state);
if (!result)
{
return state;
}
else
{
return -1;
}
}
int luat_mobile_get_local_ip(int sim_id, int cid, ip_addr_t *ip_v4, ip_addr_t *ip_v6)
{
int i;
struct netif *netif = netif_find_by_cid(cid);
if (netif)
{
if (ip_v4)
{
*ip_v4 = netif->ip_addr;
}
if (ip_v6)
{
ip_v6->type = 0xff;
for(i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++)
{
if (netif->ip6_addr_state[i] & IP6_ADDR_VALID)
{
*ip_v6 = netif->ip6_addr[i];
}
}
}
return 0;
}
else
{
if (ip_v4)
{
ip_v4->type = 0xff;
}
if (ip_v6)
{
ip_v6->type = 0xff;
}
return -1;
}
}
/* -------------------------------------------------- cell info begin -------------------------------------------------- */
uint8_t luat_mobile_rssi_to_csq(int8_t rssi)
{
if (rssi <= -113)
{
return 0;
}
else if (rssi < -52)
{
return (rssi + 113) >> 1;
}
else
{
return 31;
}
}
static void ec618_cell_to_luat_cell(BasicCellListInfo *bcListInfo, luat_mobile_cell_info_t *info)
{
info->gsm_info_valid = 0;
if (!bcListInfo->sCellPresent && !bcListInfo->nCellNum)
{
info->lte_info_valid = 0;
return;
}
if (!bcListInfo->sCellPresent)
{
info->lte_service_info.cid = 0;
}
else
{
info->lte_service_info.cid = bcListInfo->sCellInfo.cellId;
info->lte_service_info.band = bcListInfo->sCellInfo.band;
info->lte_service_info.dlbandwidth = bcListInfo->sCellInfo.dlBandWidth;
info->lte_service_info.ulbandwidth = bcListInfo->sCellInfo.ulBandWidth;
info->lte_service_info.is_tdd = bcListInfo->sCellInfo.isTdd;
info->lte_service_info.earfcn = bcListInfo->sCellInfo.earfcn;
info->lte_service_info.pci = bcListInfo->sCellInfo.phyCellId;
info->lte_service_info.tac = bcListInfo->sCellInfo.tac;
info->lte_service_info.snr = bcListInfo->sCellInfo.snr;
info->lte_service_info.rsrp = bcListInfo->sCellInfo.rsrp;
info->lte_service_info.rsrq = bcListInfo->sCellInfo.rsrq;
info->lte_service_info.rssi = bcListInfo->sCellInfo.rsrp - bcListInfo->sCellInfo.rsrq + (bcListInfo->sCellInfo.rssiCompensation/100);
info->lte_service_info.mcc = bcListInfo->sCellInfo.plmn.mcc;
if (0xf000 == (bcListInfo->sCellInfo.plmn.mncWithAddInfo & 0xf000))
{
info->lte_service_info.mnc = bcListInfo->sCellInfo.plmn.mncWithAddInfo & 0x0fff;
}
else
{
info->lte_service_info.mnc = bcListInfo->sCellInfo.plmn.mncWithAddInfo;
}
}
if (!bcListInfo->nCellNum)
{
info->lte_neighbor_info_num = 0;
}
else
{
uint8_t j = 0;
for(uint8_t i = 0; i < bcListInfo->nCellNum; i++)
{
if (bcListInfo->nCellList[i].cellInfoValid)
{
info->lte_info[j].cid = bcListInfo->nCellList[i].cellId;
info->lte_info[j].tac = bcListInfo->nCellList[i].tac;
info->lte_info[j].mcc = bcListInfo->nCellList[i].plmn.mcc;
if (0xf000 == (bcListInfo->nCellList[i].plmn.mncWithAddInfo & 0xf000))
{
info->lte_info[j].mnc = bcListInfo->nCellList[i].plmn.mncWithAddInfo & 0x0fff;
}
else
{
info->lte_info[j].mnc = bcListInfo->nCellList[i].plmn.mncWithAddInfo;
}
}
else
{
info->lte_info[j].cid = 0;
info->lte_info[j].tac = 0;
info->lte_info[j].mcc = 0;
info->lte_info[j].mnc = 0;
}
info->lte_info[j].earfcn = bcListInfo->nCellList[i].earfcn;
info->lte_info[j].pci = bcListInfo->nCellList[i].phyCellId;
info->lte_info[j].snr = bcListInfo->nCellList[i].snr;
info->lte_info[j].rsrp = bcListInfo->nCellList[i].rsrp;
info->lte_info[j].rsrq = bcListInfo->nCellList[i].rsrq;
if ((info->lte_info[j].mcc == 0x0460) && (info->lte_info[j].mnc != 0x0015))
{
j++;
}
}
info->lte_neighbor_info_num = j;
}
}
static void ec618_signal_to_luat_signal(CmiMmCesqInd *cesq_info, luat_mobile_signal_strength_info_t *info)
{
uint8_t zero[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
info->luat_mobile_gw_signal_strength_vaild = 0;
if (memcmp(zero, cesq_info, sizeof(CmiMmCesqInd)))
{
info->luat_mobile_lte_signal_strength_vaild = 1;
if (cesq_info->rsrp != CMI_MM_NOT_DETECT_RSRP)
{
if (cesq_info->rsrp > 0)
{
info->lte_signal_strength.rsrp = (cesq_info->rsrp - 141);
}
else
{
info->lte_signal_strength.rsrp = (cesq_info->rsrp - 140);
}
}
else
{
info->lte_signal_strength.rsrp = -999;
}
if (cesq_info->rsrq != CMI_MM_NOT_DETECT_RSRQ)
{
if (cesq_info->rsrq <= 0)
{
info->lte_signal_strength.rsrq = (cesq_info->rsrq - 39) >> 1;
}
else if (cesq_info->rsrq <= 34)
{
info->lte_signal_strength.rsrq = (cesq_info->rsrq - 40) >> 1;
}
else
{
info->lte_signal_strength.rsrq = (cesq_info->rsrq - 41) >> 1;
}
}
else
{
info->lte_signal_strength.rsrq = -999;
}
if (cesq_info->rsrp != CMI_MM_NOT_DETECT_RSRP &&
cesq_info->rsrq != CMI_MM_NOT_DETECT_RSRQ)
{
info->lte_signal_strength.rssi = info->lte_signal_strength.rsrp - info->lte_signal_strength.rsrq + (cesq_info->rssiCompensation/100);
}
else
{
info->lte_signal_strength.rssi = -999;
}
info->lte_signal_strength.snr = cesq_info->snr;
}
else
{
info->luat_mobile_lte_signal_strength_vaild = 0;
}
}
int luat_mobile_get_cell_info(luat_mobile_cell_info_t *info)
{
BasicCellListInfo bcListInfo;
int result = appGetECBCInfoSync(&bcListInfo);
if (!result)
{
ec618_cell_to_luat_cell(&bcListInfo, info);
return 0;
}
else
{
return -1;
}
}
int luat_mobile_get_cell_info_async(uint8_t max_time)
{
soc_mobile_search_cell_info_async(max_time);
return 0;
}
int luat_mobile_get_last_notify_cell_info(luat_mobile_cell_info_t *info)
{
BasicCellListInfo bcListInfo;
soc_mobile_get_cell_info(&bcListInfo);
ec618_cell_to_luat_cell(&bcListInfo, info);
return 0;
}
int luat_mobile_get_signal_strength_info(luat_mobile_signal_strength_info_t *info)
{
return luat_mobile_get_last_notify_signal_strength_info(info);
}
int luat_mobile_get_signal_strength(uint8_t *csq)
{
return luat_mobile_get_last_notify_signal_strength(csq);
}
int luat_mobile_get_last_notify_signal_strength_info(luat_mobile_signal_strength_info_t *info)
{
CmiMmCesqInd cesq_info;
soc_mobile_get_signal(&cesq_info);
ec618_signal_to_luat_signal(&cesq_info, info);
return 0;
}
int luat_mobile_get_last_notify_signal_strength(uint8_t *csq)
{
*csq = soc_mobile_get_csq();
return 0;
}
/* --------------------------------------------------- cell info end --------------------------------------------------- */
/* ------------------------------------------------ mobile status begin ----------------------------------------------- */
LUAT_MOBILE_REGISTER_STATUS_E luat_mobile_get_register_status(void)
{
CeregGetStateParams param;
int result = appGetCeregStateSync(&param);
if (!result)
{
return param.state;
}
return LUAT_MOBILE_STATUS_UNKNOW;
}
int luat_mobile_event_register_handler(luat_mobile_event_callback_t callback_fun)
{
soc_mobile_event_register_handler(callback_fun);
return 0;
}
int luat_mobile_event_deregister_handler(void)
{
soc_mobile_event_deregister_handler();
return 0;
}
int luat_mobile_sms_event_register_handler(luat_mobile_sms_event_callback_t callback_fun)
{
soc_mobile_sms_event_register_handler(callback_fun);
return 0;
}
/* ------------------------------------------------- mobile status end ------------------------------------------------ */
extern soc_mobile_set_rrc_release_time(uint8_t s);
void luat_mobile_set_rrc_auto_release_time(uint8_t s)
{
soc_mobile_set_rrc_release_time(s);
}
extern void soc_mobile_release_rrc_pause(uint8_t onoff);
void luat_mobile_rrc_auto_release_pause(uint8_t onoff)
{
soc_mobile_release_rrc_pause(onoff);
}
extern void soc_mobile_rrc_release_once(void);
void luat_mobile_rrc_release_once(void)
{
soc_mobile_rrc_release_once();
}
int luat_mobile_reset_stack(void)
{
soc_mobile_reset_stack();
return 0;
}
int luat_mobile_set_period_work(uint32_t get_cell_period, uint32_t check_sim_period, uint8_t search_cell_time)
{
soc_mobile_set_period(get_cell_period, check_sim_period, search_cell_time);
return 0;
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_base.h"
#include "luat_otp.h"
// EC618提供的头文件没有OTP相关的API, 以下调用的均为隐藏API
typedef enum
{
FLASH_OTP_ERASE = 0,
FLASH_OTP_WRITE,
FLASH_OTP_READ,
FLASH_OTP_LOCK
}FLASH_OTP_OPS;
uint8_t QSPI_FLASH_OTP_Handle(FLASH_OTP_OPS opType, uint32_t addr, uint8_t* bufPtr, uint8_t length);
int luat_otp_read(int zone, char* buff, size_t offset, size_t len) {
uint8_t ret = 0;
if (zone >= 1 && zone <= 3) {
ret = QSPI_FLASH_OTP_Handle(FLASH_OTP_READ, ((uint32_t)zone << 16) + (offset), (uint8_t*)buff, len);
if (ret == 0) {
return (offset + len) > luat_otp_size(zone) ? luat_otp_size(zone) - offset : len;
}
return 0;
}
return -1;
}
int luat_otp_write(int zone, char* buff, size_t offset, size_t len) {
uint8_t ret = 0;
if (zone >= 1 && zone <= 3) {
ret = QSPI_FLASH_OTP_Handle(FLASH_OTP_WRITE, ((uint32_t)zone << 16) + (offset), (uint8_t*)buff, len);
if (ret == 0) {
return (offset + len) > luat_otp_size(zone) ? luat_otp_size(zone) - offset : len;
}
return 0;
}
return -1;
}
int luat_otp_erase(int zone, size_t offset, size_t len) {
if (zone >= 1 && zone <= 3) {
return QSPI_FLASH_OTP_Handle(FLASH_OTP_ERASE, (uint32_t)zone << 16, NULL, 0);
}
return -1;
}
int luat_otp_lock(int zone) {
if (zone >= 1 && zone <= 3) {
return QSPI_FLASH_OTP_Handle(FLASH_OTP_LOCK, (uint32_t)zone << 16, NULL, 0);
}
return -1;
}
int luat_otp_size(int zone) {
if (zone >= 1 && zone <= 3) {
return 256;
}
return 0;
}

View File

@@ -0,0 +1,274 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* PWM操作
*
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#ifdef __LUATOS__
#include "luat_malloc.h"
#include "luat_msgbus.h"
#include "luat_timer.h"
#endif
#include "luat_pwm.h"
#include "luat_rtos.h"
#include "timer.h"
#include "hal_adc.h"
#include "ic.h"
#include "hal_trim.h"
#include "timer.h"
#include "ec618.h"
#include "clock.h"
#include "pad.h"
#include "luat_debug.h"
#include "RTE_Device.h"
#define EIGEN_TIMER(n) ((TIMER_TypeDef *) (AP_TIMER0_BASE_ADDR + 0x1000*n))
static signed char if_initialized_timer(const int channel)
{
if( 0 != EIGEN_TIMER(channel)->TCCR )
{
return -1;
}
return 0;
}
#define PWM_CH_MAX (6)
static int g_s_pnum_set[PWM_CH_MAX] = {0}; /*设置PWM脉冲个数*/
static volatile int g_s_pnum_update[PWM_CH_MAX] = {0};/*当前PWM个数*/
/*最高频率应是26M*/
#define MAX_FREQ (26*1000*1000)
typedef struct pwm_ctx
{
TimerPwmConfig_t timer_config;
uint32_t freq;
uint32_t pulse;
uint32_t pnum;
}pwm_ctx_t;
typedef struct pwm_map
{
int pwm_ch; // 对外展示的pwm id
int clockId;
int clockId_slect;
int time_req;
int pad;
}pwm_map_t;
static const pwm_map_t maps[] = {
#ifdef RTE_PWM0
{.pwm_ch=0, .clockId=FCLK_TIMER0, .clockId_slect=FCLK_TIMER0_SEL_26M, .time_req=PXIC0_TIMER0_IRQn, .pad=RTE_PWM0},
#endif
#ifdef RTE_PWM1
{.pwm_ch=1, .clockId=FCLK_TIMER1, .clockId_slect=FCLK_TIMER1_SEL_26M, .time_req=PXIC0_TIMER1_IRQn, .pad=RTE_PWM1},
#endif
#ifdef RTE_PWM2
{.pwm_ch=2, .clockId=FCLK_TIMER2, .clockId_slect=FCLK_TIMER2_SEL_26M, .time_req=PXIC0_TIMER2_IRQn, .pad=RTE_PWM2},
#endif
// #ifdef RTE_PWM3
// {.pwm_ch=3, .clockId=FCLK_TIMER3, .clockId_slect=FCLK_TIMER3_SEL_26M, .time_req=PXIC0_TIMER3_IRQn, .pad=RTE_PWM3},
// #endif
#ifdef RTE_PWM4
{.pwm_ch=4, .clockId=FCLK_TIMER4, .clockId_slect=FCLK_TIMER4_SEL_26M, .time_req=PXIC0_TIMER4_IRQn, .pad=RTE_PWM4},
#endif
// #ifdef RTE_PWM5
// {.pwm_ch=5, .clockId=FCLK_TIMER5, .clockId_slect=FCLK_TIMER5_SEL_26M, .time_req=PXIC0_TIMER5_IRQn, .pad=RTE_PWM5},
// #endif
// 以下为固定映射
/*
10 -- GPIO 01 -- PAD 16 ---> LCD_RST
11 -- GPIO 02 -- PAD 17
12 -- GPIO 16 -- PAD 31
13 -- GPIO 17 -- PAD 32 xxx 不可用
14 -- GPIO 18 -- PAD 33 ---> UART1_RX
15 -- GPIO 19 -- PAD 34 ---> UART1_TX xxx 不可用
*/
{.pwm_ch=10, .clockId=FCLK_TIMER0, .clockId_slect=FCLK_TIMER0_SEL_26M, .time_req=PXIC0_TIMER0_IRQn, .pad=16},
{.pwm_ch=11, .clockId=FCLK_TIMER1, .clockId_slect=FCLK_TIMER1_SEL_26M, .time_req=PXIC0_TIMER1_IRQn, .pad=17},
{.pwm_ch=12, .clockId=FCLK_TIMER2, .clockId_slect=FCLK_TIMER2_SEL_26M, .time_req=PXIC0_TIMER2_IRQn, .pad=31},
// {.pwm_ch=13, .clockId=FCLK_TIMER3, .clockId_slect=FCLK_TIMER3_SEL_26M, .time_req=PXIC0_TIMER3_IRQn, .pad=32},
{.pwm_ch=14, .clockId=FCLK_TIMER4, .clockId_slect=FCLK_TIMER4_SEL_26M, .time_req=PXIC0_TIMER4_IRQn, .pad=33},
// {.pwm_ch=15, .clockId=FCLK_TIMER5, .clockId_slect=FCLK_TIMER5_SEL_26M, .time_req=PXIC0_TIMER5_IRQn, .pad=34},
};
static pwm_ctx_t pwms[PWM_CH_MAX];
static int luat_pwm_mapid(int channel) {
int map_id = -1;
for (size_t i = 0; i < sizeof(maps) / sizeof(pwm_map_t); i++)
{
if (maps[i].pwm_ch == channel) {
map_id = i;
break;
}
}
return map_id;
}
PLAT_PA_RAMCODE static void Timer_ISR()
{
volatile int i = 0;
// PWM 3/5 通道需要跳过, 其中 3 是 tick64, 5是CP占用了
for(i = 0;i < 5;i++)
{
if (i == 3)
continue;
if (TIMER_getInterruptFlags(i) & TIMER_MATCH2_INTERRUPT_FLAG)
{
TIMER_clearInterruptFlags(i, TIMER_MATCH2_INTERRUPT_FLAG);
g_s_pnum_update[i]++;
if (g_s_pnum_update[i] >= g_s_pnum_set[i])
{
//luat_pwm_close(i);
TIMER_updatePwmDutyCycle(i,0);
//luat_pwm_update_dutycycle(i,0);
TIMER_stop(i);
//LUAT_DEBUG_PRINT("PWM STOP %d",g_s_pnum_update[i]);
g_s_pnum_update[i] = 0;
}
}
}
}
int luat_pwm_open(int channel, size_t freq, size_t pulse, int pnum) {
PadConfig_t config = {0};
int map_id = luat_pwm_mapid(channel);
if (map_id == -1)
return -1;
if (freq > MAX_FREQ)
return -2;
if (pulse > 100)
pulse = 100;
if(if_initialized_timer(channel % 10) < 0)
{
return -4; // hardware timer is used
}
// LUAT_DEBUG_PRINT("luat_pwm_open get timer_id %d",timer_id);
PAD_getDefaultConfig(&config);
config.mux = PAD_MUX_ALT5;
// 为支持复用, 只取低位
channel = channel % 10;
g_s_pnum_set[channel] = pnum;
PAD_setPinConfig(maps[map_id].pad, &config);
CLOCK_setClockSrc(maps[map_id].clockId, maps[map_id].clockId_slect);
CLOCK_setClockDiv(maps[map_id].clockId, 1);
TIMER_driverInit();
pwms[channel].timer_config.pwmFreq_HZ = freq;
pwms[channel].timer_config.srcClock_HZ = GPR_getClockFreq(maps[map_id].clockId);
pwms[channel].timer_config.dutyCyclePercent = pulse;
TIMER_setupPwm(channel, &pwms[channel].timer_config);
if(0 != pnum)
{
TIMER_interruptConfig(channel, TIMER_MATCH0_SELECT, TIMER_INTERRUPT_DISABLED);
TIMER_interruptConfig(channel, TIMER_MATCH1_SELECT, TIMER_INTERRUPT_DISABLED);
TIMER_interruptConfig(channel, TIMER_MATCH2_SELECT, TIMER_INTERRUPT_LEVEL);
XIC_SetVector(maps[map_id].time_req,Timer_ISR);
XIC_EnableIRQ(maps[map_id].time_req);
}
TIMER_start(channel);
return 0;
}
int luat_pwm_update_dutycycle(int channel,size_t pulse)
{
int map_id = luat_pwm_mapid(channel);
if (map_id == -1)
return -1;
channel = channel % 10;
pwms[channel].timer_config.dutyCyclePercent = pulse;
TIMER_setupPwm(channel, &pwms[channel].timer_config);
return 0;
}
int luat_pwm_setup(luat_pwm_conf_t* conf)
{
int channel = conf->channel;
int map_id = luat_pwm_mapid(channel);
if (map_id == -1)
return -1;
if (conf->precision != 100) {
// 当且仅支持100分辨率,等驱动重构完再改
return -1;
}
channel = channel % 10;
// 判断一下是否只修改了占空比. 当且仅当频率相同,pnum为0(即持续输出),才支持单独变更
if (pwms[channel].timer_config.pwmFreq_HZ == conf->period && conf->pnum == 0) {
if (conf->pulse != pwms[channel].timer_config.dutyCyclePercent) {
pwms[channel].timer_config.dutyCyclePercent = conf->pulse;
TIMER_updatePwmDutyCycle(conf->channel % 10, conf->pulse);
return 0;
}
}
return luat_pwm_open(conf->channel,conf->period,conf->pulse,conf->pnum);
}
int luat_pwm_capture(int channel,int freq)
{
int map_id = luat_pwm_mapid(channel);
if (map_id == -1)
return -1;
return EIGEN_TIMER(channel % 10)->TMR[0];
}
int luat_pwm_close(int channel)
{
int map_id = luat_pwm_mapid(channel);
if (map_id == -1)
return -1;
luat_pwm_update_dutycycle(channel, 0);
luat_rtos_task_sleep(1);
TIMER_stop(channel % 10);
pwms[channel % 10].timer_config.pwmFreq_HZ = 0; // 作为标志位
g_s_pnum_update[channel % 10] = 0;
g_s_pnum_set[channel % 10] = 0;
// 恢复GPIO默认配置
return 0;
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_base.h"
#include "luat_rtc.h"
#include "common_api.h"
#include "time.h"
#include "osasys.h"
#include "luat_debug.h"
static uint32_t g_s_local_tz = 32;
int luat_rtc_set(struct tm *tblock){
uint32_t Timer1 = (((tblock->tm_year+1900)<<16)&0xfff0000) | (((tblock->tm_mon+1)<<8)&0xff00) | ((tblock->tm_mday)&0xff);
uint32_t Timer2 = ((tblock->tm_hour<<24)&0xff000000) | ((tblock->tm_min<<16)&0xff0000) | ((tblock->tm_sec<<8)&0xff00) | g_s_local_tz;
uint32_t ret = OsaTimerSync(0, SET_LOCAL_TIME, Timer1, Timer2, 0);
if (ret == 0){
mwAonSetUtcTimeSyncFlag(1);
}
return 0;
}
int luat_rtc_get(struct tm *tblock){
struct tm *t = gmtime(NULL);
memcpy(tblock,t,sizeof(struct tm));
return 0;
}
#ifdef __LUATOS__
void luat_rtc_set_tamp32(uint32_t tamp) {
Time_UserDataStruct Time;
Date_UserDataStruct Date;
Tamp2UTC(tamp, &Date, &Time, 0);
if (OsaTimerSync(0,
SET_LOCAL_TIME,
((uint32_t)Date.Year<<16)|((uint32_t)Date.Mon<<8)|((uint32_t)Date.Day),
((uint32_t)Time.Hour<<24)|((uint32_t)Time.Min<<16)|((uint32_t)Time.Sec<<8)|g_s_local_tz,0
))
{
LUAT_DEBUG_PRINT("sync NITZ time fail");
}
else
{
mwAonSetUtcTimeSyncFlag(TRUE); //set to 1 when NITZ triggered
}
}
int luat_rtc_timer_start(int id, struct tm *tblock){
return -1;
}
int luat_rtc_timer_stop(int id){
return -1;
}
#endif

View File

@@ -0,0 +1,433 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_rtos.h"
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "timers.h"
#include "cmsis_os2.h"
typedef struct
{
void *timer;
luat_rtos_timer_callback_t call_back;
void *user_param;
uint8_t is_repeat;
}luat_rtos_user_timer_t;
int luat_rtos_task_create(luat_rtos_task_handle *task_handle, uint32_t stack_size, uint8_t priority, const char *task_name, luat_rtos_task_entry task_fun, void* user_data, uint16_t event_cout)
{
if (!task_handle) return -1;
*task_handle = create_event_task(task_fun, user_data, stack_size, priority, event_cout, task_name);
return (*task_handle)?0:-1;
}
int luat_rtos_task_delete(luat_rtos_task_handle task_handle)
{
if (!task_handle) return -1;
delete_event_task(task_handle);
return 0;
}
int luat_rtos_task_suspend(luat_rtos_task_handle task_handle)
{
if (!task_handle) return -1;
vTaskSuspend(task_handle);
return 0;
}
int luat_rtos_task_resume(luat_rtos_task_handle task_handle)
{
if (!task_handle) return -1;
vTaskResume(task_handle);
return 0;
}
uint32_t luat_rtos_task_get_high_water_mark(luat_rtos_task_handle task_handle)
{
if (!task_handle) return -1;
return uxTaskGetStackHighWaterMark(task_handle);
}
void luat_rtos_task_sleep(uint32_t ms)
{
vTaskDelay(ms);
}
void luat_task_suspend_all(void)
{
vTaskSuspendAll();
}
void luat_task_resume_all(void)
{
xTaskResumeAll();
}
void *luat_get_current_task(void)
{
return xTaskGetCurrentTaskHandle();
}
int luat_rtos_event_send(luat_rtos_task_handle task_handle, uint32_t id, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t timeout)
{
if (!task_handle) return -1;
return send_event_to_task(task_handle, NULL, id, param1, param2, param3, timeout);
}
LUAT_RET luat_send_event_to_task(void *task_handle, uint32_t id, uint32_t param1, uint32_t param2, uint32_t param3)
{
if (!task_handle) return -1;
return send_event_to_task(task_handle, NULL, id, param1, param2, param3, LUAT_WAIT_FOREVER);
}
LUAT_RET luat_wait_event_from_task(void *task_handle, uint32_t wait_event_id, luat_event_t *out_event, void *call_back, uint32_t ms)
{
if (!task_handle) return -1;
return get_event_from_task(task_handle, wait_event_id, (void *)out_event, call_back, ms);
}
/**
* 等同于luat_rtos_semaphore_create时init_count = 0
*/
void *luat_mutex_create(void)
{
SemaphoreHandle_t sem = xSemaphoreCreateBinary();
if (sem)
{
xSemaphoreGive(sem);
}
return sem;
}
LUAT_RET luat_mutex_lock(void *mutex)
{
return luat_rtos_semaphore_take(mutex, LUAT_WAIT_FOREVER);
}
LUAT_RET luat_mutex_unlock(void *mutex)
{
return luat_rtos_semaphore_release(mutex);
}
void luat_mutex_release(void *mutex)
{
luat_rtos_semaphore_delete(mutex);
}
int luat_rtos_semaphore_create(luat_rtos_semaphore_t *semaphore_handle, uint32_t init_count)
{
if (!semaphore_handle) return -1;
SemaphoreHandle_t sem = NULL;
if (init_count <= 1)
{
sem = xSemaphoreCreateBinary();
if (!sem)
return -1;
if (!init_count)
xSemaphoreGive(sem);
}
else
{
sem = xSemaphoreCreateCounting(init_count, init_count);
if (!sem)
return -1;
}
*semaphore_handle = (luat_rtos_semaphore_t)sem;
return 0;
}
int luat_rtos_semaphore_delete(luat_rtos_semaphore_t semaphore_handle)
{
if (!semaphore_handle) return -1;
vSemaphoreDelete(semaphore_handle);
return 0;
}
int luat_rtos_semaphore_take(luat_rtos_semaphore_t semaphore_handle, uint32_t timeout)
{
if (!semaphore_handle) return -1;
if (pdTRUE == xSemaphoreTake(semaphore_handle, timeout))
return 0;
return -1;
}
int luat_rtos_semaphore_release(luat_rtos_semaphore_t semaphore_handle)
{
if (!semaphore_handle) return -1;
if (osIsInISRContext())
{
BaseType_t yield = pdFALSE;
if (pdTRUE == xSemaphoreGiveFromISR(semaphore_handle, &yield))
{
portYIELD_FROM_ISR(yield);
return 0;
}
return -1;
}
else
{
if (pdTRUE == xSemaphoreGive(semaphore_handle))
return 0;
return -1;
}
}
int luat_rtos_mutex_create(luat_rtos_mutex_t *mutex_handle)
{
if (!mutex_handle) return -1;
QueueHandle_t pxNewQueue = NULL;
pxNewQueue = xSemaphoreCreateRecursiveMutex();
if (!pxNewQueue)
return -1;
*mutex_handle = pxNewQueue;
return 0;
}
int luat_rtos_mutex_lock(luat_rtos_mutex_t mutex_handle, uint32_t timeout)
{
if (!mutex_handle) return -1;
if (pdFALSE == xSemaphoreTakeRecursive(mutex_handle, timeout))
return -1;
return 0;
}
int luat_rtos_mutex_unlock(luat_rtos_mutex_t mutex_handle)
{
if (!mutex_handle) return -1;
if (pdFALSE == xSemaphoreGiveRecursive(mutex_handle))
return -1;
return 0;
}
int luat_rtos_mutex_delete(luat_rtos_mutex_t mutex_handle)
{
if (!mutex_handle) return -1;
vSemaphoreDelete(mutex_handle);
return 0;
}
int luat_rtos_queue_create(luat_rtos_queue_t *queue_handle, uint32_t item_count, uint32_t item_size)
{
if (!queue_handle) return -1;
QueueHandle_t pxNewQueue;
pxNewQueue = xQueueCreate(item_count, item_size);
if (!pxNewQueue)
return -1;
*queue_handle = pxNewQueue;
return 0;
}
int luat_rtos_queue_delete(luat_rtos_queue_t queue_handle)
{
if (!queue_handle) return -1;
vQueueDelete ((QueueHandle_t)queue_handle);
return 0;
}
int luat_rtos_queue_send(luat_rtos_queue_t queue_handle, void *item, uint32_t item_size, uint32_t timeout)
{
if (!queue_handle || !item) return -1;
if (osIsInISRContext())
{
BaseType_t pxHigherPriorityTaskWoken;
if (xQueueSendToBackFromISR(queue_handle, item, &pxHigherPriorityTaskWoken) != pdPASS)
return -1;
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
return 0;
}
else
{
if (xQueueSendToBack (queue_handle, item, timeout) != pdPASS)
return -1;
}
return 0;
}
int luat_rtos_queue_recv(luat_rtos_queue_t queue_handle, void *item, uint32_t item_size, uint32_t timeout)
{
if (!queue_handle || !item)
return -1;
BaseType_t yield = pdFALSE;
if (osIsInISRContext())
{
if (xQueueReceiveFromISR(queue_handle, item, &yield) != pdPASS)
return -1;
portYIELD_FROM_ISR(yield);
return 0;
}
else
{
if (xQueueReceive(queue_handle, item, timeout) != pdPASS)
return -1;
}
return 0;
}
static void s_timer_callback(TimerHandle_t hTimer)
{
luat_rtos_user_timer_t *timer = (luat_rtos_user_timer_t *)pvTimerGetTimerID(hTimer);
if (!timer)
return;
if (!timer->is_repeat)
{
xTimerStop(hTimer, 0);
}
if (timer->call_back)
{
timer->call_back(timer->user_param);
}
}
/* ----------------------------------- timer ----------------------------------- */
void *luat_create_rtos_timer(void *cb, void *param, void *task_handle)
{
luat_rtos_user_timer_t *timer = malloc(sizeof(luat_rtos_user_timer_t));
if (timer)
{
timer->timer = xTimerCreate(NULL, 1, 1, timer, s_timer_callback);
if (!timer->timer)
{
free(timer);
return NULL;
}
timer->call_back = cb;
timer->user_param = param;
timer->is_repeat = 0;
}
return timer;
}
int luat_start_rtos_timer(void *timer, uint32_t ms, uint8_t is_repeat)
{
luat_rtos_user_timer_t *htimer = (luat_rtos_user_timer_t *)timer;
BaseType_t pxHigherPriorityTaskWoken;
if (osIsInISRContext())
{
if ((xTimerStopFromISR(htimer->timer, &pxHigherPriorityTaskWoken) != pdPASS))
return -1;
htimer->is_repeat = is_repeat;
if ((xTimerChangePeriodFromISR(htimer->timer, ms, &pxHigherPriorityTaskWoken) != pdPASS))
return -1;
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
}
else
{
if (xTimerIsTimerActive (htimer->timer))
{
if (xTimerStop(htimer->timer, LUAT_WAIT_FOREVER) != pdPASS)
return -1;
}
htimer->is_repeat = is_repeat;
if (xTimerChangePeriod(htimer->timer, ms, LUAT_WAIT_FOREVER) != pdPASS)
return -1;
}
return 0;
}
void luat_stop_rtos_timer(void *timer)
{
luat_rtos_user_timer_t *htimer = (luat_rtos_user_timer_t *)timer;
if (osIsInISRContext())
{
BaseType_t pxHigherPriorityTaskWoken;
if ((xTimerStopFromISR(htimer->timer, &pxHigherPriorityTaskWoken) != pdPASS))
return ;
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
}
else
{
if (xTimerIsTimerActive (htimer->timer))
{
xTimerStop(htimer->timer, LUAT_WAIT_FOREVER);
}
}
}
void luat_release_rtos_timer(void *timer)
{
luat_rtos_user_timer_t *htimer = (luat_rtos_user_timer_t *)timer;
xTimerDelete(htimer->timer, LUAT_WAIT_FOREVER);
free(htimer);
}
int luat_rtos_timer_start(luat_rtos_timer_t timer_handle, uint32_t timeout, uint8_t repeat, luat_rtos_timer_callback_t callback_fun, void *user_param)
{
if (!timer_handle) return -1;
luat_rtos_user_timer_t *htimer = (luat_rtos_user_timer_t *)timer_handle;
BaseType_t pxHigherPriorityTaskWoken;
if (osIsInISRContext())
{
if ((xTimerStopFromISR(htimer->timer, &pxHigherPriorityTaskWoken) != pdPASS))
return -1;
htimer->is_repeat = repeat;
htimer->call_back = callback_fun;
htimer->user_param = user_param;
if ((xTimerChangePeriodFromISR(htimer->timer, timeout, &pxHigherPriorityTaskWoken) != pdPASS))
return -1;
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
}
else
{
if (xTimerIsTimerActive (htimer->timer))
{
if (xTimerStop(htimer->timer, LUAT_WAIT_FOREVER) != pdPASS)
return -1;
}
htimer->is_repeat = repeat;
htimer->call_back = callback_fun;
htimer->user_param = user_param;
if (xTimerChangePeriod(htimer->timer, timeout, LUAT_WAIT_FOREVER) != pdPASS)
return -1;
}
return 0;
}
int luat_rtos_timer_is_active(luat_rtos_timer_t timer_handle)
{
if (!timer_handle) return -1;
luat_rtos_user_timer_t *htimer = (luat_rtos_user_timer_t *)timer_handle;
if (pdTRUE == xTimerIsTimerActive (htimer->timer))
return 1;
else
return 0;
}
/*------------------------------------------------ timer end----------------------------------------------- */
/* ------------------------------------------------ critical begin----------------------------------------------- */
/**
* @brief 进入临界保护
*
* @return uint32_t 退出临界保护所需参数
*/
uint32_t luat_rtos_entry_critical(void)
{
return OS_EnterCritical();
}
/**
* @brief 退出临界保护
*
* @param critical 进入临界保护时返回的参数
*/
void luat_rtos_exit_critical(uint32_t critical)
{
OS_ExitCritical(critical);
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_base.h"
#include "luat_rtos.h"
#include "luat_rtos_legacy.h"
LUAT_WEAK void luat_rtos_task_suspend_all(void)
{
luat_task_suspend_all();
}
LUAT_WEAK void luat_rtos_task_resume_all(void)
{
luat_task_resume_all();
}
luat_rtos_task_handle luat_rtos_get_current_handle(void)
{
return luat_get_current_task();
}
LUAT_WEAK int luat_rtos_event_send(luat_rtos_task_handle task_handle, uint32_t id, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t timeout)
{
if (!task_handle) return -1;
return luat_send_event_to_task(task_handle, id, param1, param2, param3);
}
LUAT_WEAK int luat_rtos_event_recv(luat_rtos_task_handle task_handle, uint32_t wait_event_id, luat_event_t *out_event, luat_rtos_event_wait_callback_t *callback_fun, uint32_t timeout)
{
if (!task_handle) return -1;
return luat_wait_event_from_task(task_handle, wait_event_id, out_event, callback_fun, timeout);
}
LUAT_WEAK int luat_rtos_message_send(luat_rtos_task_handle task_handle, uint32_t message_id, void *p_message)
{
if (!task_handle) return -1;
return luat_send_event_to_task(task_handle, message_id, p_message, 0, 0);
}
LUAT_WEAK int luat_rtos_message_recv(luat_rtos_task_handle task_handle, uint32_t *message_id, void **p_p_message, uint32_t timeout)
{
if (!task_handle) return -1;
luat_event_t event;
int result = luat_wait_event_from_task(task_handle, 0, &event, 0, timeout);
if (!result)
{
*message_id = event.id;
*p_p_message = (void *)event.param1;
}
return result;
}
LUAT_WEAK int luat_rtos_timer_create(luat_rtos_timer_t *timer_handle)
{
if (!timer_handle) return -1;
*timer_handle = luat_create_rtos_timer(NULL, NULL, NULL);
return (*timer_handle)?0:-1;
}
LUAT_WEAK int luat_rtos_timer_stop(luat_rtos_timer_t timer_handle)
{
if (!timer_handle) return -1;
luat_stop_rtos_timer(timer_handle);
return 0;
}
LUAT_WEAK int luat_rtos_timer_delete(luat_rtos_timer_t timer_handle)
{
if (!timer_handle) return -1;
luat_release_rtos_timer(timer_handle);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_base.h"
#include "luat_spi.h"
#include "common_api.h"
#include <stdio.h>
#include <string.h>
#include "bsp_custom.h"
#include "soc_spi.h"
#include "driver_gpio.h"
static uint8_t g_s_luat_spi_mode[SPI_MAX] ={0};
static int spi_exist(int id) {
if (id < SPI_MAX) return 1;
return 0;
}
#ifdef __LUATOS__
int luat_spi_device_config(luat_spi_device_t* spi_dev) {
if (!spi_exist(spi_dev->bus_id))
return -1;
uint8_t spi_mode = SPI_MODE_0;
if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
else if(spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_2;
else if(spi_dev->spi_config.CPHA)spi_mode = SPI_MODE_1;
SPI_SetNewConfig(spi_dev->bus_id, spi_dev->spi_config.bandrate, spi_mode);
return 0;
}
int luat_spi_bus_setup(luat_spi_device_t* spi_dev){
if (!spi_exist(spi_dev->bus_id))
return -1;
uint8_t spi_mode = SPI_MODE_0;
if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
else if(spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_2;
else if(spi_dev->spi_config.CPHA)spi_mode = SPI_MODE_1;
if (spi_dev->bus_id)
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_13, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_14, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_15, 0), 1, 0, 0);
}
else
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_9, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_10, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_11, 0), 1, 0, 0);
}
g_s_luat_spi_mode[spi_dev->bus_id] = spi_dev->spi_config.mode;
// LLOGD("SPI_MasterInit luat_bus_%d:%d dataw:%d spi_mode:%d bandrate:%d ",bus_id,luat_spi[bus_id].id, spi_dev->spi_config.dataw, spi_mode, spi_dev->spi_config.bandrate);
SPI_MasterInit(spi_dev->bus_id, spi_dev->spi_config.dataw, spi_mode, spi_dev->spi_config.bandrate, NULL, NULL);
return 0;
}
#endif
int luat_spi_setup(luat_spi_t* spi) {
if (!spi_exist(spi->id))
return -1;
uint8_t spi_mode = SPI_MODE_0;
if(spi->CPHA&&spi->CPOL)spi_mode = SPI_MODE_3;
else if(spi->CPOL)spi_mode = SPI_MODE_2;
else if(spi->CPHA)spi_mode = SPI_MODE_1;
if (spi->id)
{
if (HAL_GPIO_12 == spi->cs)
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_12, 0), 1, 0, 0);
}
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_13, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_14, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_15, 0), 1, 0, 0);
}
else
{
if (HAL_GPIO_8 == spi->cs)
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_8, 0), 1, 0, 0);
}
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_9, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_10, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_11, 0), 1, 0, 0);
}
g_s_luat_spi_mode[spi->id] = spi->mode;
// LLOGD("SPI_MasterInit luat_spi%d:%d dataw:%d spi_mode:%d bandrate:%d ",spi_id,luat_spi[spi_id].id, spi->dataw, spi_mode, spi->bandrate);
SPI_MasterInit(spi->id, spi->dataw, spi_mode, spi->bandrate, NULL, NULL);
return 0;
}
//关闭SPI成功返回0
int luat_spi_close(int spi_id) {
return 0;
}
//收发SPI数据返回接收字节数
int luat_spi_transfer(int spi_id, const char* send_buf, size_t send_length, char* recv_buf, size_t recv_length) {
if (!spi_exist(spi_id))
return -1;
if(g_s_luat_spi_mode[spi_id])
{
if (SPI_BlockTransfer(spi_id, send_buf, recv_buf, recv_length))
{
return 0;
}
else
{
return recv_length;
}
}
else
{
if (SPI_FlashBlockTransfer(spi_id, send_buf, send_length, recv_buf, recv_length))
{
return 0;
}
else
{
return recv_length;
}
}
return 0;
}
//收SPI数据返回接收字节数
int luat_spi_recv(int spi_id, char* recv_buf, size_t length) {
if (!spi_exist(spi_id))
return -1;
if (SPI_BlockTransfer(spi_id, recv_buf, recv_buf, length))
{
return 0;
}
else
{
return length;
}
}
//发SPI数据返回发送字节数
int luat_spi_send(int spi_id, const char* send_buf, size_t length) {
if (!spi_exist(spi_id))
return -1;
if (SPI_BlockTransfer(spi_id, send_buf, send_buf, length))
{
return 0;
}
else
{
return length;
}
}
int luat_spi_no_block_transfer(int spi_id, uint8_t *tx_buff, uint8_t *rx_buff, size_t len, void *CB, void *pParam)
{
if (SPI_IsTransferBusy(spi_id)) return -1;
SPI_SetCallbackFun(spi_id, CB, pParam);
SPI_SetNoBlock(spi_id);
return SPI_TransferEx(spi_id, tx_buff, rx_buff, len, 0, 1);
}

View File

@@ -0,0 +1,342 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "common_api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "luat_base.h"
#include "luat_uart.h"
#include "luat_rtos.h"
#ifdef __LUATOS__
#include "luat_malloc.h"
#include "luat_msgbus.h"
#include "luat_timer.h"
#endif
#include <stdio.h>
#include "bsp_custom.h"
#include "bsp_common.h"
#include "driver_gpio.h"
#include "driver_uart.h"
#define MAX_DEVICE_COUNT (UART_MAX+1)
static luat_uart_ctrl_param_t uart_cb[MAX_DEVICE_COUNT]={0};
static Buffer_Struct g_s_vuart_rx_buffer;
static uint32_t g_s_vuart_rx_base_len;
typedef struct
{
timer_t *rs485_timer;
union
{
uint32_t rs485_param;
struct
{
uint32_t wait_time:30;
uint32_t rx_level:1;
uint32_t is_485used:1;
}rs485_param_bit;
};
uint16_t unused;
uint8_t alt_type;
uint8_t rs485_pin;
}serials_info;
static serials_info g_s_serials[MAX_DEVICE_COUNT - 1] ={0};
#ifdef __LUATOS__
static LUAT_RT_RET_TYPE luat_uart_wait_timer_cb(LUAT_RT_CB_PARAM)
{
uint32_t uartid = (uint32_t)param;
if (g_s_serials[uartid].rs485_param_bit.is_485used) {
GPIO_Output(g_s_serials[uartid].rs485_pin, g_s_serials[uartid].rs485_param_bit.rx_level);
}
uart_cb[uartid].sent_callback_fun(uartid, NULL);
}
void luat_uart_recv_cb(int uart_id, uint32_t data_len){
rtos_msg_t msg;
msg.handler = l_uart_handler;
msg.ptr = NULL;
msg.arg1 = uart_id;
msg.arg2 = data_len;
int re = luat_msgbus_put(&msg, 0);
}
void luat_uart_sent_cb(int uart_id, void *param){
rtos_msg_t msg;
msg.handler = l_uart_handler;
msg.ptr = NULL;
msg.arg1 = uart_id;
msg.arg2 = 0;
int re = luat_msgbus_put(&msg, 0);
}
#endif
int luat_uart_pre_setup(int uart_id, uint8_t use_alt_type)
{
if (uart_id >= MAX_DEVICE_COUNT){
return 0;
}
g_s_serials[uart_id].alt_type = use_alt_type;
}
void luat_uart_sent_dummy_cb(int uart_id, void *param) {;}
void luat_uart_recv_dummy_cb(int uart_id, void *param) {;}
static int32_t luat_uart_cb(void *pData, void *pParam){
uint32_t uartid = (uint32_t)pData;
uint32_t State = (uint32_t)pParam;
uint32_t len;
// DBG("luat_uart_cb pData:%d pParam:%d ",uartid,State);
switch (State){
case UART_CB_TX_BUFFER_DONE:
#ifdef __LUATOS__
if (g_s_serials[uartid].rs485_param_bit.is_485used && g_s_serials[uartid].rs485_param_bit.wait_time)
{
luat_start_rtos_timer(g_s_serials[uartid].rs485_timer, g_s_serials[uartid].rs485_param_bit.wait_time, 0);
}
else
#endif
{
uart_cb[uartid].sent_callback_fun(uartid, NULL);
}
break;
case UART_CB_TX_ALL_DONE:
#ifdef __LUATOS__
if (g_s_serials[uartid].rs485_param_bit.is_485used) {
GPIO_Output(g_s_serials[uartid].rs485_pin, g_s_serials[uartid].rs485_param_bit.rx_level);
}
#endif
uart_cb[uartid].sent_callback_fun(uartid, NULL);
break;
case UART_CB_RX_BUFFER_FULL:
//只有UART1可以唤醒
#ifdef __LUATOS__
if (UART_ID1 == uartid)
{
uart_cb[uartid].recv_callback_fun(uartid, 0xffffffff);
}
#else
if (UART_ID1 == uartid)
{
uart_cb[uartid].recv_callback_fun(uartid, 0);
}
#endif
break;
case UART_CB_RX_TIMEOUT:
len = Uart_RxBufferRead(uartid, NULL, 0);
uart_cb[uartid].recv_callback_fun(uartid, len);
break;
case UART_CB_RX_NEW:
#if 0
len = Uart_RxBufferRead(uartid, NULL, 0);
uart_cb[uartid].recv_callback_fun(uartid, len);
#endif
break;
case UART_CB_ERROR:
break;
}
}
int luat_uart_setup(luat_uart_t* uart) {
if (!luat_uart_exist(uart->id)) {
DBG("uart.setup FAIL!!!");
return -1;
}
if (uart->id >= MAX_DEVICE_COUNT){
OS_ReInitBuffer(&g_s_vuart_rx_buffer, uart->bufsz?uart->bufsz:1024);
g_s_vuart_rx_base_len = g_s_vuart_rx_buffer.MaxLen;
return 0;
}
switch (uart->id)
{
case UART_ID0:
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_14, 0), 3, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_15, 0), 3, 0, 0);
break;
case UART_ID1:
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_18, 0), 1, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_19, 0), 1, 0, 0);
break;
case UART_ID2:
// #ifdef __LUATOS__
if (g_s_serials[UART_ID2].alt_type)
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_12, 0), 5, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_13, 0), 5, 0, 0);
}
else
// #endif
{
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_10, 0), 3, 0, 0);
GPIO_IomuxEC618(GPIO_ToPadEC618(HAL_GPIO_11, 0), 3, 0, 0);
}
break;
default:
break;
}
int parity = 0;
if (uart->parity == 1)parity = UART_PARITY_ODD;
else if (uart->parity == 2)parity = UART_PARITY_EVEN;
int stop_bits = (uart->stop_bits)==1?UART_STOP_BIT1:UART_STOP_BIT2;
{
uart_cb[uart->id].recv_callback_fun = luat_uart_recv_dummy_cb;
uart_cb[uart->id].sent_callback_fun = luat_uart_sent_dummy_cb;
Uart_BaseInitEx(uart->id, uart->baud_rate, 1024, uart->bufsz?uart->bufsz:1024, (uart->data_bits), parity, stop_bits, luat_uart_cb);
#ifdef __LUATOS__
g_s_serials[uart->id].rs485_param_bit.is_485used = (uart->pin485 < HAL_GPIO_NONE)?1:0;
g_s_serials[uart->id].rs485_pin = uart->pin485;
g_s_serials[uart->id].rs485_param_bit.rx_level = uart->rx_level;
g_s_serials[uart->id].rs485_param_bit.wait_time = uart->delay/1000;
if (!g_s_serials[uart->id].rs485_timer) {
g_s_serials[uart->id].rs485_timer = luat_create_rtos_timer(luat_uart_wait_timer_cb, uart->id, NULL);
}
GPIO_IomuxEC618(GPIO_ToPadEC618(g_s_serials[uart->id].rs485_pin, 0), 0, 0, 0);
GPIO_Config(g_s_serials[uart->id].rs485_pin, 0, g_s_serials[uart->id].rs485_param_bit.rx_level);
#endif
}
return 0;
}
int luat_uart_write(int uartid, void* data, size_t length) {
if (luat_uart_exist(uartid)) {
if (uartid >= MAX_DEVICE_COUNT){
usb_serial_output(4,data,length);
}else{
#ifdef __LUATOS__
if (g_s_serials[uartid].rs485_param_bit.is_485used) GPIO_Output(g_s_serials[uartid].rs485_pin, !g_s_serials[uartid].rs485_param_bit.rx_level);
#endif
Uart_TxTaskSafe(uartid, data, length);
}
}
else {
DBG("not such uart id=%ld", uartid);
}
return 0;
}
int luat_uart_read(int uartid, void* buffer, size_t len) {
int rcount = 0;
if (luat_uart_exist(uartid)) {
if (uartid >= MAX_DEVICE_COUNT){
rcount = (g_s_vuart_rx_buffer.Pos > len)?len:g_s_vuart_rx_buffer.Pos;
memcpy(buffer, g_s_vuart_rx_buffer.Data, rcount);
OS_BufferRemove(&g_s_vuart_rx_buffer, rcount);
if (!g_s_vuart_rx_buffer.Pos && g_s_vuart_rx_buffer.MaxLen > g_s_vuart_rx_base_len)
{
OS_ReInitBuffer(&g_s_vuart_rx_buffer, g_s_vuart_rx_base_len);
}
}
else
{
rcount = Uart_RxBufferRead(uartid, (uint8_t *)buffer, len);
}
}
return rcount;
}
int luat_uart_close(int uartid) {
if (luat_uart_exist(uartid)) {
if (uartid >= MAX_DEVICE_COUNT){
OS_DeInitBuffer(&g_s_vuart_rx_buffer);
return 0;
}
Uart_DeInit(uartid);
}
return 0;
}
int luat_uart_exist(int uartid) {
// EC618仅支持 uart0,uart1,uart2
// uart0是ulog的输出
// uart1是支持下载,也是用户可用
// uart2是用户可用的
// if (uartid == 0 || uartid == 1 || uartid == 2) {
// 暂时只支持UART1和UART2
if (uartid >= LUAT_VUART_ID_0) uartid = MAX_DEVICE_COUNT - 1;
return (uartid >= MAX_DEVICE_COUNT)?0:1;
}
static void luat_usb_recv_cb(uint8_t channel, uint8_t *input, uint32_t len){
if (input){
OS_BufferWrite(&g_s_vuart_rx_buffer, input, len);
#ifdef __LUATOS__
rtos_msg_t msg;
msg.handler = l_uart_handler;
msg.ptr = NULL;
msg.arg1 = LUAT_VUART_ID_0;
msg.arg2 = len;
int re = luat_msgbus_put(&msg, 0);
#endif
if (uart_cb[UART_MAX].recv_callback_fun){
uart_cb[UART_MAX].recv_callback_fun(LUAT_VUART_ID_0,len);
}
}else{
switch(len){
case 0:
DBG("usb serial connected");
break;
default:
DBG("usb serial disconnected");
break;
}
}
}
int luat_setup_cb(int uartid, int received, int sent) {
if (luat_uart_exist(uartid)) {
#ifdef __LUATOS__
if (uartid >= UART_MAX){
set_usb_serial_input_callback(luat_usb_recv_cb);
}else{
if (received){
uart_cb[uartid].recv_callback_fun = luat_uart_recv_cb;
}
if (sent){
uart_cb[uartid].sent_callback_fun = luat_uart_sent_cb;
}
}
#endif
}
return 0;
}
int luat_uart_ctrl(int uart_id, LUAT_UART_CTRL_CMD_E cmd, void* param){
if (luat_uart_exist(uart_id)) {
if (uart_id >= MAX_DEVICE_COUNT){
uart_id = UART_MAX;
set_usb_serial_input_callback(luat_usb_recv_cb);
}
if (cmd == LUAT_UART_SET_RECV_CALLBACK){
uart_cb[uart_id].recv_callback_fun = param;
}else if(cmd == LUAT_UART_SET_SENT_CALLBACK){
uart_cb[uart_id].sent_callback_fun = param;
}
}
return 0;
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "wdt.h"
#include "clock.h"
#include "slpman.h"
int luat_wdt_setup(size_t timeout)
{
if(timeout < 1 || timeout > 60)
{
return -1;
}
GPR_setClockSrc(FCLK_WDG, FCLK_WDG_SEL_32K);
GPR_setClockDiv(FCLK_WDG, timeout);
WdtConfig_t wdtConfig;
wdtConfig.mode = WDT_INTERRUPT_RESET_MODE;
wdtConfig.timeoutValue = 32768U;
WDT_init(&wdtConfig);
WDT_start();
return 0;
}
int luat_wdt_set_timeout(size_t timeout)
{
if(timeout < 1 || timeout > 60)
{
return -1;
}
WDT_kick();
WDT_stop();
WDT_deInit();
luat_wdt_setup(timeout);
return 0;
}
int luat_wdt_feed(void)
{
WDT_kick();
slpManAonWdtFeed();
return 0;
}
int luat_wdt_close(void)
{
WDT_stop();
WDT_deInit();
return 0;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "luat_wifiscan.h"
#include "common_api.h"
#include "ps_lib_api.h"
#include "luat_debug.h"
int32_t luat_get_wifiscan_cell_info(luat_wifiscan_set_info_t * set_info,luat_wifisacn_get_info_t* get_info)
{
int32_t ret;
if (set_info == NULL || get_info ==NULL)
{
return -1;
}
SetWifiScanParams wifiscanreq;
GetWifiScanInfo pWifiScanInfo;
wifiscanreq.maxTimeOut=set_info->maxTimeOut;
wifiscanreq.round=set_info->round;
wifiscanreq.maxBssidNum=set_info->maxBssidNum;
wifiscanreq.scanTimeOut=set_info->scanTimeOut;
wifiscanreq.wifiPriority=set_info->wifiPriority;
ret=appGetWifiScanInfo(&wifiscanreq, &pWifiScanInfo);
if (ret == 0)
{
if (pWifiScanInfo.bssidNum >= LUAT_MAX_WIFI_BSSID_NUM)
{
get_info->bssidNum = LUAT_MAX_WIFI_BSSID_NUM;
}
else
{
get_info->bssidNum =pWifiScanInfo.bssidNum;
}
get_info->rsvd = pWifiScanInfo.rsvd;
for (int i = 0; i < pWifiScanInfo.bssidNum; i++)
{
get_info->ssidHexLen[i] = pWifiScanInfo.ssidHexLen[i];
for (int j = 0; j < pWifiScanInfo.ssidHexLen[i]; j++)
{
get_info->ssidHex[i][j] = pWifiScanInfo.ssidHex[i][j];
}
get_info->rssi[i] = pWifiScanInfo.rssi[i];
get_info->channel[i] = pWifiScanInfo.channel[i];
for (int n = 0; n < 6; n++)
{
get_info->bssid[i][n] = pWifiScanInfo.bssid[i][n];
}
}
return 0;
}
return -1;
}