Просмотр исходного кода

Merge branch 'master' of https://gitee.com/openLuat/LuatOS

alienwalker 2 лет назад
Родитель
Сommit
6e0eab04ae

+ 6 - 16
components/iconv/luat_lib_iconv.c

@@ -94,7 +94,7 @@ static iconv_t get_iconv_t(lua_State *L, int i) {
 @api iconv.open(tocode, fromcode)
 @string 释义:目标编码格式<br>取值:gb2312/ucs2/ucs2be/utf8
 @string 释义:源编码格式<br>取值:gb2312/ucs2/ucs2be/utf8
-@return table 编码转换函数的转换句柄
+@return userdata 编码转换函数的转换句柄,若不存在会返回nil
 @usage
 --unicode大端编码 转化为 utf8编码
 local iconv = iconv.open("utf8", "ucs2be")
@@ -103,11 +103,11 @@ static int Liconv_open(lua_State *L) {
     const char *tocode = luaL_checkstring(L, 1);
     const char *fromcode = luaL_checkstring(L, 2);
     iconv_t cd = iconv_open(tocode, fromcode);
-    if (cd != (iconv_t)(-1))
+    if (cd != (iconv_t)(-1)) {
         push_iconv_t(L, cd);    /* ok */
-    else
-        lua_pushnil(L);         /* erro */
-    return 1;
+        return 1;
+    }
+    return 0;
 }
 
 /*
@@ -170,7 +170,7 @@ static int Liconv(lua_State *L) {
     lua_pushlstring(L, outbufs, obsize - obleft);
     if (hasone == 1)
         lua_concat(L, 2);
-    free(outbufs);
+    luat_heap_free(outbufs);
     return 1;   /* Done */
 }
 
@@ -212,16 +212,6 @@ static int Liconvlist(lua_State *L) {
 
 #endif
 
-/*
-关闭字符编码转换
-@api iconv.close(cd)
-@string iconv.open返回的句柄
-@return nil 无返回值
-@usage
---关闭字符编码转换
-local iconv = iconv.open("utf8", "ucs2be")
-iconv.close(iconv)
-*/
 static int Liconv_close(lua_State *L) {
     iconv_t cd = get_iconv_t(L, 1);
     if (iconv_close(cd) == 0)

+ 1 - 1
components/lora2/luat_lib_lora.c

@@ -59,7 +59,7 @@ static int l_lora_handler(lua_State* L, void* ptr) {
             case LORA_RX_DONE:
                 lua_pushstring(L, "rx_done");
                 lora_data_t* rx_buff = (lora_data_t*)msg->arg2;
-                lua_pushlstring(L, rx_buff->payload,rx_buff->size);
+                lua_pushlstring(L, (const char *)rx_buff->payload,rx_buff->size);
                 lua_pushinteger(L, rx_buff->size);
                 lua_call(L, 4, 0);
                 luat_heap_free(rx_buff);

+ 5 - 5
components/lora2/sx126x/sx126x-board.c

@@ -44,17 +44,17 @@ void SX126xSetNss2(lora_device_t* lora_device,uint8_t lev ){
     luat_gpio_set( lora_device->lora_pin_cs, lev);
 }
 
-void lora_spi_transfer(lora_device_t* lora_device, const char* send_buf, size_t send_length, char* recv_buf, size_t recv_length){
+void lora_spi_transfer(lora_device_t* lora_device, const uint8_t* send_buf, size_t send_length, uint8_t* recv_buf, size_t recv_length){
     if (lora_device->lora_spi_id == 255){
-        luat_spi_device_transfer(lora_device->lora_spi_device, send_buf, send_length, recv_buf, recv_length);
+        luat_spi_device_transfer(lora_device->lora_spi_device, (const char *)send_buf, send_length, (char *)recv_buf, recv_length);
     }else{
         SX126xSetNss2(lora_device,0);
         // luat_spi_transfer(lora_device->lora_spi_id, send_buf, send_length, recv_buf, recv_length);
         if (send_length){
-            luat_spi_send(lora_device->lora_spi_id, send_buf, send_length);
+            luat_spi_send(lora_device->lora_spi_id, (const char *)send_buf, send_length);
         }
         if (recv_length){
-            luat_spi_recv(lora_device->lora_spi_id, recv_buf, recv_length);
+            luat_spi_recv(lora_device->lora_spi_id, (char *)recv_buf, recv_length);
         }
         SX126xSetNss2(lora_device,1);
     }
@@ -124,7 +124,7 @@ void SX126xWriteBuffer2( lora_device_t* lora_device,uint8_t offset, uint8_t *buf
     cmd[0] = RADIO_WRITE_BUFFER;
     cmd[1] = offset;
     memcpy(cmd+2,buffer,size);
-    luat_spi_send(lora_device->lora_spi_id, cmd, 2+size);
+    luat_spi_send(lora_device->lora_spi_id, (const char *)cmd, 2+size);
     lora_spi_transfer(lora_device, cmd, 2+size,NULL,0);
     SX126xWaitOnBusy2(lora_device );
 }

+ 36 - 8
components/mobile/luat_lib_mobile.c

@@ -788,6 +788,22 @@ mobile.flymode(0,true)
 mobile.config(mobile.CONF_RESELTOWEAKNCELL, 15)
 mobile.config(mobile.CONF_STATICCONFIG, 1) --开启网络静态优化
 mobile.flymode(0,false)
+
+-- EC618设置SIM写入次数的统计
+-- 关闭统计
+mobile.config(mobile.CONF_SIM_WC_MODE, 0)
+-- 开启统计, 默认也是开启的.
+mobile.config(mobile.CONF_SIM_WC_MODE, 1)
+-- 读取统计值,异步, 需要通过系统消息SIM_IND获取
+sys.subscribe("SIM_IND", function(stats, value)
+    log.info("SIM_IND", stats)
+    if stats == "SIM_WC" then
+        log.info("sim", "write counter", value)
+    end
+end)
+mobile.config(mobile.CONF_SIM_WC_MODE, 2)
+-- 清空统计值
+mobile.config(mobile.CONF_SIM_WC_MODE, 3)
  */
 static int l_mobile_config(lua_State* L) {
     uint8_t item = luaL_optinteger(L, 1, 0);
@@ -967,6 +983,8 @@ static const rotable_Reg_t reg_mobile[] = {
 	{"CONF_PSM_MODE",           ROREG_INT(MOBILE_CONF_PSM_MODE)},
 	//@const CONF_CE_MODE number attach模式,0为EPS ONLY 2为混合,遇到IMSI detach脱网问题,设置为0,注意设置为EPS ONLY时会取消短信功能
 	{"CONF_CE_MODE",            ROREG_INT(MOBILE_CONF_CE_MODE)},
+    //@const CONF_SIM_WC_MODE number SIM写入次数的配置和读取
+    {"CONF_SIM_WC_MODE",        ROREG_INT(MOBILE_CONF_SIM_WC_MODE)},
 	//@const PIN_VERIFY number 验证PIN码操作
 	{"PIN_VERIFY",              ROREG_INT(LUAT_SIM_PIN_VERIFY)},
 	//@const PIN_CHANGE number 更换PIN码操作
@@ -991,6 +1009,7 @@ static int l_mobile_event_handle(lua_State* L, void* ptr) {
     uint8_t status;
     int ret;
 
+
     rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
     event = msg->arg1;
     index = msg->arg2 >> 8;
@@ -1016,13 +1035,14 @@ static int l_mobile_event_handle(lua_State* L, void* ptr) {
 sim卡状态变化
 SIM_IND
 @usage
-sys.subscribe("SIM_IND", function(status)
+sys.subscribe("SIM_IND", function(status, value)
     -- status的取值有:
-    -- RDY SIM卡就绪
-    -- NORDY 无SIM卡
-    -- SIM_PIN 需要输入PIN
-    -- GET_NUMBER 获取到电话号码(不一定有值)
-    log.info("sim status", status)
+    -- RDY SIM卡就绪, value为nil
+    -- NORDY 无SIM卡, value为nil
+    -- SIM_PIN 需要输入PIN, value为nil
+    -- GET_NUMBER 获取到电话号码(不一定有值), value为nil
+    -- SIM_WC SIM卡的写入次数统计,掉电归0, value为统计值
+    log.info("sim status", status, value)
 end)
 */
         switch (status)
@@ -1047,6 +1067,14 @@ end)
             lua_pushstring(L, "GET_NUMBER");
             lua_call(L, 2, 0);
             break;
+        case LUAT_MOBILE_SIM_WC:
+            lua_pushstring(L, "SIM_IND");
+            lua_pushstring(L, "SIM_WC");
+            uint32_t tmp = 0;
+            memcpy(&tmp, ptr, 4);
+            lua_pushinteger(L, tmp);
+            lua_call(L, 3, 0);
+            break;
         default:
             break;
         }
@@ -1166,12 +1194,12 @@ end)
 }
 
 // 给luat_mobile_event_register_handler 注册用, 给lua层发消息
-void luat_mobile_event_cb(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status) {
+void luat_mobile_event_cb(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status, void* ptr) {
     rtos_msg_t msg = {
         .handler = l_mobile_event_handle,
         .arg1 = event,
         .arg2 = (index << 8) + status ,
-        .ptr = NULL
+        .ptr = ptr
     };
     luat_msgbus_put(&msg, 0);
 }

+ 4 - 0
components/mobile/luat_mobile.h

@@ -536,6 +536,7 @@ typedef enum LUAT_MOBILE_SIM_STATUS
 	LUAT_MOBILE_SIM_NEED_PIN,
 	LUAT_MOBILE_SIM_ENTER_PIN_RESULT,
 	LUAT_MOBILE_SIM_NUMBER,
+	LUAT_MOBILE_SIM_WC
 }LUAT_MOBILE_SIM_STATUS_E;
 
 typedef enum LUAT_MOBILE_REGISTER_STATUS
@@ -756,6 +757,9 @@ enum
 	MOBILE_CONF_T3324MAXVALUE,
 	MOBILE_CONF_PSM_MODE,
 	MOBILE_CONF_CE_MODE,
+	MOBILE_CONF_SIM_WC_MODE
 };
 
+uint32_t luat_mobile_sim_write_counter(void);
+
 #endif

+ 60 - 19
components/u8g2/luat_lib_u8g2.c

@@ -54,15 +54,12 @@ typedef struct luat_u8g2_dev_reg
     uint16_t spi_i2c; // 使用 I2C 0, 使用 SPI 1
 }luat_u8g2_dev_reg_t;
 
-static const luat_u8g2_dev_reg_t custom_devregs = {
-    .name="custom", 
-    .devcb=u8g2_Setup_ssd1306_i2c_128x64_noname_f
-};
-
 static const luat_u8g2_dev_reg_t devregs[] = {
     // ssd1306是默认值
     {.name="ssd1306", .w=128, .h=64, .spi_i2c=0, .devcb=u8g2_Setup_ssd1306_i2c_128x64_noname_f},       // ssd1306 128x64,I2C
     {.name="ssd1306", .w=128, .h=64, .spi_i2c=1, .devcb=u8g2_Setup_ssd1306_128x64_noname_f},           // ssd1306 128x64,SPI
+    {.name="custom",  .w=0,   .h=0,  .spi_i2c=0, .devcb=u8g2_Setup_custom_i2c_noname_f},                  // custom,I2C
+    {.name="custom",  .w=0,   .h=0,  .spi_i2c=1, .devcb=u8g2_Setup_custom_noname_f},                      // custom,SPI
     {.name="ssd1309", .w=128, .h=64, .spi_i2c=1, .devcb=u8g2_Setup_ssd1309_128x64_noname2_f},           // ssd1309 128x64,SPI
     {.name="ssd1322", .w=256, .h=64, .spi_i2c=0, .devcb=u8g2_Setup_ssd1322_nhd_256x64_f},              // ssd1322 128x64
     {.name="sh1106",  .w=128, .h=64, .spi_i2c=0, .devcb=u8g2_Setup_sh1106_i2c_128x64_noname_f},        // sh1106 128x64,I2C
@@ -223,8 +220,55 @@ static int l_u8g2_begin(lua_State *L) {
             spi_cs = luaL_checkinteger(L, -1);
         }
         lua_pop(L, 1);
+        
+    }
+
+    if (lua_istable(L, 2) && strcmp("custom", conf->cname) == 0){
+        LLOGD("table 2 custom");
+        lua_pushliteral(L, "width");
+        lua_gettable(L, 2);
+        if (lua_isinteger(L, -1)) {
+            conf->w = luaL_checkinteger(L, -1);
+        }
+        lua_pop(L, 1);
 
+        lua_pushliteral(L, "height");
+        lua_gettable(L, 2);
+        if (lua_isinteger(L, -1)) {
+            conf->h = luaL_checkinteger(L, -1);
+        }
+        lua_pop(L, 1);
+
+        lua_pushliteral(L, "sleepcmd");
+        lua_gettable(L, 2);
+        if (lua_isinteger(L, -1)) {
+            conf->sleepcmd = luaL_checkinteger(L, -1);
+        }
+        lua_pop(L, 1);
+
+        lua_pushliteral(L, "wakecmd");
+        lua_gettable(L, 2);
+        if (lua_isinteger(L, -1)) {
+            conf->wakecmd = luaL_checkinteger(L, -1);
+        }
+        lua_pop(L, 1);
+
+        luat_u8g2_custom_t *cst = luat_heap_malloc(sizeof(luat_u8g2_custom_t));
+        lua_pushstring(L, "initcmd");
+        lua_gettable(L, 2);
+        if (lua_istable(L, -1)) {
+            cst->init_cmd_count = lua_rawlen(L, -1);
+            cst->initcmd = luat_heap_malloc(cst->init_cmd_count * sizeof(uint32_t));
+            for (size_t i = 1; i <= cst->init_cmd_count; i++){
+                lua_geti(L, -1, i);
+                cst->initcmd[i-1] = luaL_checkinteger(L, -1);
+                lua_pop(L, 1);
+            }
+        }
+        lua_pop(L, 1);
+        conf->userdata = cst;
     }
+
     LLOGD("driver %s mode %s", conf->cname, mode);
     if (luat_u8g2_setup(conf)) {
         conf = NULL;
@@ -1107,21 +1151,17 @@ LUAT_WEAK uint8_t u8x8_luat_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t
 int luat_u8g2_setup_default(luat_u8g2_conf_t *conf) {
     u8g2_t* u8g2 = &conf->u8g2;
     const luat_u8g2_dev_reg_t* devreg = NULL;
-    LLOGD("pinType %d", pinType);
-    if (strcmp("custom", conf->cname) == 0){
-        LLOGD("custom dev %s", conf->cname);
-        devreg = &custom_devregs;
-    }else{
-        devreg = search_dev_reg(conf, 0);
-        if (devreg == NULL) {
-            LLOGD("unkown dev %s", conf->cname);
-            return -1;
-        }
+    // LLOGD("pinType %d", pinType);
+    devreg = search_dev_reg(conf, pinType == 5?1:0);
+    if (devreg == NULL) {
+        LLOGD("unkown dev %s", conf->cname);
+        return -1;
     }
+    // LLOGD("devreg name:%s spi_i2c:%d", devreg->name,devreg->spi_i2c);
     if (pinType == 1) {
         devreg->devcb(u8g2, conf->direction, u8x8_byte_sw_i2c, u8x8_luat_gpio_and_delay_default);
-        u8g2->u8x8.pins[U8X8_PIN_I2C_CLOCK] = i2c_scl;
-        u8g2->u8x8.pins[U8X8_PIN_I2C_DATA] = i2c_sda;
+        u8x8_SetPin(u8g2_GetU8x8(u8g2), U8X8_PIN_I2C_CLOCK, i2c_scl);
+        u8x8_SetPin(u8g2_GetU8x8(u8g2), U8X8_PIN_I2C_DATA, i2c_sda);
     }else if (pinType == 2) {
         devreg->devcb(u8g2, conf->direction, u8x8_luat_byte_hw_i2c_default, u8x8_luat_gpio_and_delay_default);
         //LLOGD("setup disp i2c.hw");
@@ -1135,10 +1175,10 @@ int luat_u8g2_setup_default(luat_u8g2_conf_t *conf) {
         LLOGI("no such u8g2 mode!!");
         return -1;
     }
-    #ifdef U8G2_USE_DYNAMIC_ALLOC
+#ifdef U8G2_USE_DYNAMIC_ALLOC
     conf->buff_ptr = (uint8_t *)luat_heap_malloc(u8g2_GetBufferSize(u8g2));
     u8g2_SetBufferPtr(u8g2, conf->buff_ptr);
-    #endif
+#endif
     u8g2_InitDisplay(u8g2);
     u8g2_SetPowerSave(u8g2, 0);
     return 0;
@@ -1210,6 +1250,7 @@ int hw_spi_begin(uint8_t spi_mode, uint32_t max_hz, uint8_t cs_pin )
 }
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 uint8_t u8x8_luat_byte_4wire_hw_spi_default(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
+    // LLOGI("u8x8_luat_byte_4wire_hw_spi_default msg:%d arg_int:%d",msg,arg_int);
     switch(msg)
     {
         case U8X8_MSG_BYTE_SEND:

+ 9 - 2
components/u8g2/luat_u8g2.h

@@ -2,16 +2,23 @@
 #include "luat_base.h"
 #include "u8g2.h"
 
+typedef struct luat_u8g2_custom {
+    size_t init_cmd_count;
+    uint32_t *initcmd; // 实际命令长度与init_cmd_count相同
+}luat_u8g2_custom_t;
+
 typedef struct luat_u8g2_conf
 {
     size_t w;
     size_t h;
     int lua_ref;
     char* cname; // 控制器名称, 例如SSD1306
-    // void* ptr;
-    const u8g2_cb_t* direction;//方向 
+    u8g2_cb_t* direction;//方向 
     u8g2_t u8g2;
+    uint16_t sleepcmd;
+    uint16_t wakecmd;
     uint8_t* buff_ptr;
+    void* userdata;
 } luat_u8g2_conf_t;
 
 int luat_u8g2_setup(luat_u8g2_conf_t *conf);

+ 1 - 5
components/u8g2/u8g2.h

@@ -86,11 +86,6 @@
  */
 #define U8G2_USE_DYNAMIC_ALLOC
 
-/*
-  U8G2 uses the same static array
- */
-// #define U8G2_USE_ONE_STATIC_BUFF
-
 /* U8g2 feature selection, see also https://github.com/olikraus/u8g2/wiki/u8g2optimization */
 
 /*
@@ -671,6 +666,7 @@ uint8_t *u8g2_m_48_30_f(uint8_t *page_cnt);
 /*==========================================*/
 /* u8g2_d_setup.c generated code start */
 void u8g2_Setup_custom_i2c_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_custom_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1305_128x32_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1305_128x32_adafruit_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1305_128x32_noname_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);

+ 207 - 2
components/u8g2/u8g2_d_setup.c

@@ -8,11 +8,20 @@ void u8g2_Setup_custom_i2c_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 {
   uint8_t tile_buf_height;
   uint8_t *buf;
-  // u8g2_SetupDisplay(u8g2, u8x8_d_custom_128x64_noname, u8x8_cad_custom_fast_i2c, byte_cb, gpio_and_delay_cb);
+  // u8g2_SetupDisplay(u8g2, u8x8_d_custom_noname, u8x8_cad_custom_fast_i2c, byte_cb, gpio_and_delay_cb);
+  u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_16_8_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+void u8g2_Setup_custom_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  // u8g2_SetupDisplay(u8g2, u8x8_d_custom_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
+  u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
   buf = u8g2_m_16_8_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
 }
-
 /* ssd1305 */
 /* ssd1305 1 */
 void u8g2_Setup_ssd1305_128x32_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
@@ -7819,6 +7828,34 @@ void u8g2_Setup_sed1330_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
   buf = u8g2_m_30_16_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
 }
+/* sed1330 */
+/* sed1330 1 */
+void u8g2_Setup_sed1330_256x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_256x128, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_16_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
+/* sed1330 2 */
+void u8g2_Setup_sed1330_256x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_256x128, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_16_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
+/* sed1330 f */
+void u8g2_Setup_sed1330_256x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_256x128, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_16_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
 /* ra8835 */
 /* ra8835 1 */
 void u8g2_Setup_ra8835_nhd_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
@@ -7875,6 +7912,34 @@ void u8g2_Setup_ra8835_320x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_m
   buf = u8g2_m_40_30_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
 }
+/* sed1330 */
+/* sed1330 1 */
+void u8g2_Setup_sed1330_320x200_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_320x200, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_40_25_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
+/* sed1330 2 */
+void u8g2_Setup_sed1330_320x200_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_320x200, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_40_25_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
+/* sed1330 f */
+void u8g2_Setup_sed1330_320x200_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_sed1330_320x200, u8x8_cad_100, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_40_25_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
+}
 /* max7219 */
 /* max7219 1 */
 void u8g2_Setup_max7219_64x8_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
@@ -7959,6 +8024,34 @@ void u8g2_Setup_max7219_8x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_
   buf = u8g2_m_1_1_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_horizontal_right_lsb, rotation);
 }
+/* s1d15300 */
+/* s1d15300 1 */
+void u8g2_Setup_s1d15300_lm6023_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_s1d15300_lm6023, u8x8_cad_011, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_16_8_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* s1d15300 2 */
+void u8g2_Setup_s1d15300_lm6023_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_s1d15300_lm6023, u8x8_cad_011, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_16_8_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* s1d15300 f */
+void u8g2_Setup_s1d15300_lm6023_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_s1d15300_lm6023, u8x8_cad_011, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_16_8_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
 /* s1d15e06 */
 /* s1d15e06 1 */
 void u8g2_Setup_s1d15e06_160100_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
@@ -8043,6 +8136,118 @@ void u8g2_Setup_gu800_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg
   buf = u8g2_m_16_8_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
 }
+/* gu800 */
+/* gu800 1 */
+void u8g2_Setup_gu800_160x16_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gu800_160x16, u8x8_gu800_cad_110, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_20_2_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gu800 2 */
+void u8g2_Setup_gu800_160x16_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gu800_160x16, u8x8_gu800_cad_110, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_20_2_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gu800 f */
+void u8g2_Setup_gu800_160x16_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gu800_160x16, u8x8_gu800_cad_110, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_20_2_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1287ai */
+/* gp1287ai 1 */
+void u8g2_Setup_gp1287ai_256x50_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1287ai_256x50, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_7_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1287ai 2 */
+void u8g2_Setup_gp1287ai_256x50_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1287ai_256x50, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_7_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1287ai f */
+void u8g2_Setup_gp1287ai_256x50_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1287ai_256x50, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_7_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1247ai */
+/* gp1247ai 1 */
+void u8g2_Setup_gp1247ai_253x63_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1247ai_253x63, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_8_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1247ai 2 */
+void u8g2_Setup_gp1247ai_253x63_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1247ai_253x63, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_8_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1247ai f */
+void u8g2_Setup_gp1247ai_253x63_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1247ai_253x63, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_8_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1294ai */
+/* gp1294ai 1 */
+void u8g2_Setup_gp1294ai_256x48_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1294ai_256x48, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_6_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1294ai 2 */
+void u8g2_Setup_gp1294ai_256x48_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1294ai_256x48, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_6_2(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+/* gp1294ai f */
+void u8g2_Setup_gp1294ai_256x48_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_gp1294ai_256x48, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_32_6_f(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
 /* a2printer */
 /* a2printer 1 */
 void u8g2_Setup_a2printer_384x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)

+ 1 - 0
components/u8g2/u8x8.h

@@ -832,6 +832,7 @@ void utf8_show(void);		/* show content of UTF-8 frame buffer */
 uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 
 /* u8x8_d_XXX.c */
+uint8_t u8x8_d_custom_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1701_ea_dogs102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);

+ 1 - 1
components/u8g2/u8x8_d_lc7981.c

@@ -363,7 +363,7 @@ static const uint8_t u8x8_d_lc7981_240x128_init_seq[] = {
   U8X8_CA(0x00, 0x32),			/* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
   U8X8_CA(0x01, 0x07),			/* character/bits per pixel pitch */
   U8X8_CA(0x02, 240/8-1),		/* number of chars/byte width of the screen */
-  U8X8_CA(0x03, 128),			/* time division, issue https://github.com/olikraus/u8g2/issues/1581 */
+  U8X8_CA(0x03, 16*8-1),			/* time division */
   U8X8_CA(0x08, 0x00),			/* display start low */
   U8X8_CA(0x09, 0x00),			/* display start high */
 

+ 10 - 7
demo/iconv/main.lua

@@ -200,13 +200,16 @@ end
 
 
 sys.taskInit(function()
-    testucs2ToGb2312(string.fromHex("1162")) -- "1162"是"我"字的ucs2编码,这里调用了string.fromHex将参数转化为二进制,也就是两个字节。
-    testgb2312ToUcs2(string.fromHex("CED2")) -- "CED2"是"我"字的gb22312编码
-    testucs2beToGb2312(string.fromHex("6211")) -- "6211"是"我"字的ucs2be编码
-    testgb2312ToUcs2be(string.fromHex("CED2"))
-    testucs2ToUtf8(string.fromHex("1162"))
-    testutf8ToGb2312(string.fromHex("E68891")) -- "E68891"是"我"字的utf8编码
-    testgb2312ToUtf8(string.fromHex("CED2"))
+    while 1 do
+        sys.wait(1000)
+        testucs2ToGb2312(string.fromHex("1162")) -- "1162"是"我"字的ucs2编码,这里调用了string.fromHex将参数转化为二进制,也就是两个字节。
+        testgb2312ToUcs2(string.fromHex("CED2")) -- "CED2"是"我"字的gb22312编码
+        testucs2beToGb2312(string.fromHex("6211")) -- "6211"是"我"字的ucs2be编码
+        testgb2312ToUcs2be(string.fromHex("CED2"))
+        testucs2ToUtf8(string.fromHex("1162"))
+        testutf8ToGb2312(string.fromHex("E68891")) -- "E68891"是"我"字的utf8编码
+        testgb2312ToUtf8(string.fromHex("CED2"))
+    end
 end)
 
 -- 用户代码已结束---------------------------------------------

+ 3 - 0
luat/include/luat_mcu.h

@@ -28,5 +28,8 @@ uint64_t luat_mcu_tick64_ms(void);
 void luat_mcu_set_clk_source(uint8_t source_main, uint8_t source_32k, uint32_t delay);
 
 void luat_mcu_iomux_ctrl(uint8_t type, uint8_t sn, int pad_index, uint8_t alt, uint8_t is_input);
+
+void luat_mcu_set_hardfault_mode(int mode);
+
 #endif
 

+ 5 - 2
script/libs/rc522.lua

@@ -566,7 +566,10 @@ function rc522.write_datablock(addr,data)
     end
     if status == true then
         local status,uid = rc522.anticoll(array_id)
-        if status == true then
+        if not uid then
+            return false
+        end
+        if status == true and uid then
             rc522.select(uid)
             status = authstate( rc522_authent1b, addr,Key_B,uid )
             if status == true then
@@ -599,7 +602,7 @@ function rc522.read_datablock(addr)
     end
     if status == true then
         local status,uid = rc522.anticoll(array_id)
-        if status == true then
+        if status == true and uid then
             rc522.select(uid)
             status = authstate( rc522_authent1b, addr,Key_B,uid )
             if status == true then

+ 108 - 0
script/libs/shift595.lua

@@ -0,0 +1,108 @@
+--[[
+@module shift595
+@summary shift595 74HC595芯片
+@version 1.0
+@date    2023.08.30
+@author  lulipro
+@usage
+--注意:
+1、初始化时必须提供sclk移位时钟引脚和dat数据引脚,rclk根据应用需求可选
+2、AIR101官方核心板,底层为LuatOS-SoC_V0017_AIR101.soc,经测试此脚本库的串行时钟频率为18KHz
+
+--用法实例
+--硬件模块:双595驱动的共阳极4位数码管
+local shift595 = require("shift595")
+sys.taskInit(function() 
+
+    shift595.init(pin.PB08,pin.PB09,pin.PB10)  -- sclk,dat,rclk
+    
+    while 1 do
+        local wei = 1
+        for i = 0, 3, 1 do
+            shift595.out(0x82,shift595.MSB)--发送段数据 ,然后是位选数据
+            shift595.out(wei,shift595.MSB)--发送段数据 ,然后是位选数据
+            shift595.latch() --锁存
+            wei = wei<<1
+            sys.wait(500)
+        end
+        sys.wait(1000)
+    end
+end
+)
+
+
+
+]]
+
+local shift595 = {}
+
+local sys = require "sys"
+
+shift595.MSB=0     --字节串行输出时先发送最高位
+shift595.LSB=1     --字节串行输出时先发送最低位
+
+local SHIFT595_SCLK     --串行移位时钟引脚
+local SHIFT595_DAT      --串行数据引脚
+local SHIFT595_RCLK     --锁存信号时钟引脚
+
+
+--[[
+75hc595芯片初始化
+@api shift595.init(sclk,dat,rclk)
+@number sclk,定义驱动595串行时钟信号的引脚
+@number dat,定义驱动595串行数据的引脚
+@number rclk,定义驱动595锁存信号的引脚,可选
+@usage
+shift595.init(pin.PB08,pin.PB09,pin.PB10)  -- sclk,dat,rclk
+]]
+function shift595.init(sclk,dat,rclk)
+    SHIFT595_SCLK = gpio.setup(sclk, 1)
+    SHIFT595_DAT  = gpio.setup(dat, 1)
+    
+    if rclk then
+        SHIFT595_RCLK = gpio.setup(rclk, 1)
+    else
+        SHIFT595_RCLK = nil
+    end
+end
+
+
+--[[
+串行输出一个字节到74hc595芯片的移位寄存器中
+@api shift595.out(dat,endian)
+@number dat,发送的字节数据
+@number endian,指定发送字节数据时的大小端模式,有shift595.MSB和shift595.LSB两种参数可选。默认shift595.MSB
+@usage
+shift595.out(0x82,shift595.MSB)
+shift595.out(0x82)  --默认shift595.MSB,与上面等价
+]]
+function shift595.out(dat,endian)
+    local mbit
+    for i = 0, 7, 1 do
+        SHIFT595_SCLK(0)
+        if endian == shift595.LSB then
+            mbit = ((dat>>i)&0x01~=0) and 1 or 0
+        else
+            mbit = ((dat<<i)&0x80~=0) and 1 or 0
+        end
+        SHIFT595_DAT(mbit)
+        SHIFT595_SCLK(1)
+    end
+end
+
+
+--[[
+给74hc595芯片的RCLK线一个高脉冲,使得移位寄存器中的数据转移到锁存器中,当OE使能时,数据就输出到QA~QH引脚上。
+如果初始化时没用到rclk引脚则此函数调用无效。
+@api shift595.latch()
+@usage
+shift595.latch()
+]]
+function shift595.latch()
+    if SHIFT595_RCLK then
+        SHIFT595_RCLK(0)
+        SHIFT595_RCLK(1)
+    end
+end
+
+return shift595

+ 225 - 0
script/libs/tm1640.lua

@@ -0,0 +1,225 @@
+--[[
+@module tm1640
+@summary tm1640 数码管和LED驱动芯片
+@version 1.0
+@date    2023.08.29
+@author  lulipro
+@usage
+--注意:
+1、tm1640驱动的数码管应该选用共阴数码管
+2、tm1640也可以驱动LED,如果是LED,则应该将LED连接成共阴数码管内部相同的电路
+3、AIR101官方核心板,底层为LuatOS-SoC_V0017_AIR101.soc,经测试此脚本库的串行时钟频率为20KHz
+
+-- 用法实例
+local tm1640 = require("tm1640")
+
+sys.taskInit(function ()
+    --共阴段码表,0~9的数字
+    local NUM_TABLE_AX = {
+        [0]=0x3f,[1]=0x06,[2]=0x5b,[3]=0x4f,[4]=0x66,
+        [5]=0x6d,[6]=0x7d,[7]=0x07,[8]=0x7f,[9]=0x6f
+    };   
+
+    tm1640.init(pin.PB06,pin.PB07)  --clk,dat
+    
+    while 1 do
+        for i = 0, 9, 1 do
+            tm1640.setBright(tm1640.BRIGHT1)
+            for grid = tm1640.GRID1, tm1640.GRID16, 1 do
+                tm1640.sendDisplayData(grid,NUM_TABLE_AX[i])
+            end
+            sys.wait(200)
+            tm1640.setBright(tm1640.BRIGHT3)
+            sys.wait(200)
+            tm1640.setBright(tm1640.BRIGHT5)
+            sys.wait(200)
+            tm1640.setBright(tm1640.BRIGHT8)
+            sys.wait(200)
+        end
+
+        sys.wait(1000)
+
+        tm1640.setBright(tm1640.BRIGHT5)
+        for i = 0, 9, 1 do
+            tm1640.clear()
+            for grid = tm1640.GRID1, tm1640.GRID16, 1 do
+                tm1640.sendDisplayData(grid,NUM_TABLE_AX[i])
+                sys.wait(100)
+            end
+        end
+    end
+end)
+]]
+local tm1640 = {}
+
+local sys = require "sys"
+
+--数码管位选常量定义
+tm1640.GRID1 = 0
+tm1640.GRID2 = 1
+tm1640.GRID3 = 2
+tm1640.GRID4 = 3
+tm1640.GRID5 = 4
+tm1640.GRID6 = 5
+tm1640.GRID7 = 6
+tm1640.GRID8 = 7
+tm1640.GRID9 = 8
+tm1640.GRID10 = 9
+tm1640.GRID11 = 10
+tm1640.GRID12 = 11
+tm1640.GRID13 = 12
+tm1640.GRID14 = 13
+tm1640.GRID15 = 14
+tm1640.GRID16 = 15
+
+--八级亮度常量定义
+tm1640.BRIGHT1 = 0
+tm1640.BRIGHT2 = 1
+tm1640.BRIGHT3 = 2
+tm1640.BRIGHT4 = 3
+tm1640.BRIGHT5 = 4
+tm1640.BRIGHT6 = 5
+tm1640.BRIGHT7 = 6
+tm1640.BRIGHT8 = 7
+
+local is_display_on = 1                --显示开关标志变量
+local bright        = tm1640.BRIGHT5   --亮度级别变量
+
+local TM1640_CLK    --驱动时钟线的引脚
+local TM1640_DAT    --驱动数据线的引脚
+
+
+--串行通信起始条件
+local function tm1640_strat()
+    TM1640_CLK(1)
+    TM1640_DAT(1)
+    TM1640_DAT(0)
+    TM1640_CLK(0)
+end
+--串行通信结束条件
+local function tm1640_stop()
+    TM1640_CLK(0)
+    TM1640_DAT(0)
+    TM1640_CLK(1)
+    TM1640_DAT(1)
+end
+
+--串行发送一个字节,LSB First
+local function tm1640_writeByte(data)
+    for i = 0, 7, 1 do
+        local mbit = (data&0x01~=0) and 1 or 0
+        TM1640_DAT(mbit)
+        TM1640_CLK(1)
+        data = data>>1
+        TM1640_CLK(0)
+        --data = data>>1 将这句话放在上面是为了尽量让时钟接近50%占空比
+    end
+end
+
+
+
+--[[
+向TM1640的一个指定的位(grid)对应的显存发送指定的段数据进行显示
+@api tm1640.sendDisplayData(grid,seg_data)
+@number grid,定义位选参数,取值为tm1640.GRID1~tm1640.GRID16
+@number seg_data,定义段数据参数
+@usage
+tm1640.sendDisplayData(tm1640.GRID1,0xff)
+]]
+function tm1640.sendDisplayData(grid,seg_data)
+    if (grid >= tm1640.GRID1) and (grid <= tm1640.GRID16) then
+        tm1640_strat()
+        tm1640_writeByte(0xc0|grid)
+        tm1640_writeByte(seg_data)
+        tm1640_stop()
+    end
+end
+
+--[[
+清除TM1640的所有位(grid)对应的显存数据,即全部刷写为0
+@api tm1640.clear()
+@usage
+tm1640.clear()
+]]
+function tm1640.clear()
+    for i = tm1640.GRID1, tm1640.GRID16, 1 do
+        tm1640.sendDisplayData(i,0)
+    end
+end
+
+--[[
+打开TM1640的显示,此操作不影响显存中的数据
+@api tm1640.open()
+@usage
+tm1640.open()
+]]
+function tm1640.open()
+    is_display_on=1
+    tm1640_strat()
+    tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
+    tm1640_stop()
+end
+
+--[[
+关闭TM1640的显示,此操作不影响显存中的数据
+@api tm1640.close()
+@usage
+tm1640.close()
+]]
+function tm1640.close()
+    is_display_on=0
+    tm1640_strat()
+    tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
+    tm1640_stop()
+end
+
+--[[
+设置TM1640的显示亮度,此操作不影响显存中的数据
+@api tm1640.setBright(bri)
+@number 亮度参数,取值为tm1640.BRIGHT1~tm1640.BRIGHT8
+@usage
+tm1640.setBright(tm1640.BRIGHT8)
+]]
+function tm1640.setBright(bri)
+    if bri>tm1640.BRIGHT8 then bri = tm1640.BRIGHT8 end
+    if bri<tm1640.BRIGHT1 then bri = tm1640.BRIGHT1 end
+
+    bright = bri
+    tm1640_strat()
+    tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
+    tm1640_stop()
+end
+
+
+--[[
+TM1640的初始化
+@api tm1640.init(clk,dat,bri)
+@number clk,定义了时钟线驱动引脚
+@number dat,定义了数据线驱动引脚
+@number bri,初始亮度参数,可取的值为tm1640.BRIGHT1~tm1640.BRIGHT8。可选,默认值为tm1640.BRIGHT5。
+@usage
+tm1640.init(pin.PB06,pin.PB07)
+tm1640.init(pin.PB06,pin.PB07,tm1640.BRIGHT8)
+]]
+function tm1640.init(clk,dat,bri)
+    TM1640_CLK = gpio.setup(clk, 1)
+    TM1640_DAT = gpio.setup(dat, 1)
+
+    --设置为固定地址模式
+    tm1640_strat()
+    tm1640_writeByte(0x44)
+    tm1640_stop()
+
+    --如果设置了初始亮度
+    if bri then
+        if bri>tm1640.BRIGHT8 then bri = tm1640.BRIGHT8 end
+        if bri<tm1640.BRIGHT1 then bri = tm1640.BRIGHT1 end
+        bright = bri
+    end
+
+    tm1640.open()  --打开显示
+    tm1640.clear() --清除显存数据
+end
+
+
+return tm1640