afLib 1.3 which is supporting both SPI and UART
Dependencies: vt100 mbed afLib_1_3
Revision 0:87662653a3c6, committed 2018-04-23
- Comitter:
- Rhyme
- Date:
- Mon Apr 23 06:15:26 2018 +0000
- Child:
- 1:90652e9012b9
- Commit message:
- First UART working version
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/afLib.lib Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,1 @@ +afLib#112741fe45d1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/af_attriburtes.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,338 @@
+#include "mbed.h"
+#include <ctype.h>
+#include "af_attributes.h"
+#include "af_mgr.h"
+#include "edge_time.h"
+#include "edge_mgr.h"
+#include "edge_reset_mgr.h"
+
+
+static const af_attribute_type af_attr[] = {
+#if 1
+/* ID, Description, Type, Size */
+/* Software Reset Request */
+ { ATTR_SOFTWARE_RESET, "Software Reset", ATTRIBUTE_TYPE_BOOLEAN, 1 },
+ { ATTR_MCU_RESET_REASON, "MCU Reset Reason", ATTRIBUTE_TYPE_UTF8S, 64 },
+
+ { ATTR_LED, "LED", ATTRIBUTE_TYPE_SINT16, 2 },
+ { ATTR_IO0, "I/O 0", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_IO1, "I/O 1", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_IO2, "I/O 2", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_BUTTON, "BUTTON", ATTRIBUTE_TYPE_BOOLEAN, 2 },
+ { ATTR_IO3, "I/O 3", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_BOOT_LOADER_VER, "Bootloader Version", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_BLE_STACK_VER, "BLE Stack Version", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_FW_APP_VER, "FW Application Version", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_DEVICE_DESC, "Device Description", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_WIFI_VER, "Wi-Fi chip", ATTRIBUTE_TYPE_SINT64, 8 },
+ { ATTR_OFFLINE_SCHED, "Offline Schedules enable", ATTRIBUTE_TYPE_SINT16, 2 },
+ { ATTR_SECURITY_ENABLED, "Security Enabled", ATTRIBUTE_TYPE_SINT8, 1 }, /* ? */
+ { ATTR_UTC_OFFSET, "UTC offset data", ATTRIBUTE_TYPE_BYTES, 8 },
+ { ATTR_CONFIGURES_SSID, "Configured SSID", ATTRIBUTE_TYPE_UTF8S, 10 }, /* ? */
+ { ATTR_WIFI_BARS, "Wi-Fi Bars", ATTRIBUTE_TYPE_SINT8, 1 },
+ { ATTR_WIFI_STDY_STATE, "Wi-Fi Steady State", ATTRIBUTE_TYPE_SINT8, 1 },
+ { ATTR_COMMAND, "Command", ATTRIBUTE_TYPE_BYTES, 8 }, /* ? */
+ { ATTR_ASR_STATE, "ASR State", ATTRIBUTE_TYPE_SINT8, 1 },
+ { ATTR_LOW_BATTERY, "Low Battery Warning", ATTRIBUTE_TYPE_SINT8, 1 },
+ { ATTR_LINKED_TIMESTAMP, "Linked Timestamp", ATTRIBUTE_TYPE_SINT32, 4 },
+ { ATTR_ATTR_ACK, "Attribute ACK", ATTRIBUTE_TYPE_SINT16, 8 },
+ { ATTR_REBOOT_REASON, "Reboot Reason", ATTRIBUTE_TYPE_UTF8S, 100 },
+ { ATTR_BLE_COMMS, "BLE Comms", ATTRIBUTE_TYPE_BYTES, 12 },
+ { ATTR_MCU_INTERFACE, "MCU Interface", ATTRIBUTE_TYPE_SINT8, 1 },
+ { 0, 0, 0, 0 }
+} ;
+#endif
+
+int get_af_attr(uint16_t id)
+{
+ int i ;
+ for (i = 0 ; af_attr[i].id != 0 ; i++ ) {
+ if (id == af_attr[i].id) {
+ break ;
+ }
+ }
+ return (i) ;
+}
+
+void print_af_error(int resultCode)
+{
+ switch(resultCode) {
+ case afSUCCESS:
+ tty->printf("Operation completed successfully\n") ;
+ break ;
+ case afERROR_NO_SUCH_ATTRIBUTE:
+ tty->printf("Request was made for unknown attribute id\n") ;
+ break ;
+ case afERROR_BUSY:
+ tty->printf("Request already in progress, try again\n") ;
+ break ;
+ case afERROR_INVALID_COMMAND:
+ tty->printf("Command could not be parsed\n") ;
+ break ;
+ case afERROR_QUEUE_OVERFLOW:
+ tty->printf("Queue is full\n") ;
+ break ;
+ case afERROR_QUEUE_UNDERFLOW:
+ tty->printf("Queue is empty\n") ;
+ break ;
+ case afERROR_INVALID_PARAM:
+ tty->printf("Bad input parameter\n") ;
+ break ;
+ default:
+ tty->printf("Unknown error code %d\n", resultCode) ;
+ break ;
+ }
+}
+
+void af_print_values(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value
+)
+{
+ int i, id ;
+
+ id = get_af_attr(attributeId) ;
+
+ if (af_attr[id].id != 0) {
+ tty->printf(af_attr[id].description) ;
+ tty->printf(" : ") ;
+ switch(af_attr[id].attribute_type) {
+ case ATTRIBUTE_TYPE_BOOLEAN:
+ case ATTRIBUTE_TYPE_SINT8:
+ if (valueLen >= 1) {
+ tty->printf("%02X\n", value[0]) ;
+ }
+ break ;
+ case ATTRIBUTE_TYPE_SINT16:
+ if (valueLen >= 2) {
+ tty->printf("%02X%02X\n", value[1], value[0]) ;
+ }
+ break ;
+ case ATTRIBUTE_TYPE_SINT32:
+ if (valueLen >= 4) {
+ tty->printf("%02X%02X%02X%02X\n",
+ value[3],value[2],value[1],value[0]) ;
+ }
+ break ;
+ case ATTRIBUTE_TYPE_SINT64:
+ if (valueLen >= 8) {
+ tty->printf("%02X%02X %02X%02X %02X%02X %02X%02X\n",
+ value[7], value[6], value[5], value[4],
+ value[3], value[2], value[1], value[0]) ;
+ }
+ break ;
+ case ATTRIBUTE_TYPE_UTF8S:
+ if (valueLen > 0) {
+ for (i = 0 ; i < valueLen ; i++) {
+ if (isprint(value[i])) {
+ tty->printf("%c", value[i]) ;
+ } else if (value[i] == 0) { /* string terminator NULL */
+ break ;
+ } else {
+ tty->printf("\'%02X\'",value[i]) ;
+ }
+ }
+ tty->printf("\n") ;
+ }
+ break ;
+ case ATTRIBUTE_TYPE_BYTES:
+ default:
+ if (valueLen > 0) {
+ for (i = 0 ; i < valueLen ; i++ ) {
+ tty->printf("%02X ", value[i]) ;
+ }
+ tty->printf("\n") ;
+ }
+ break ;
+ }
+ } else {
+ if (valueLen > 0) {
+ for (i = 0 ; i < valueLen ; i++ ) {
+ tty->printf("%02X ", value[i]) ;
+ }
+ tty->printf("\n") ;
+ }
+ }
+// tty->printf("\n") ;
+}
+
+bool assignAttribute(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value,
+ bool fromRequest
+)
+{
+ bool result = true ;
+ switch(attributeId) {
+ case ATTR_LINKED_TIMESTAMP: /* timestamp */
+ set_time(valueLen, value) ; /* 68 us */
+// if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ;
+ tty->printf("timestamp = ") ;
+ print_date_wd(¤t_time) ;
+// print_time(¤t_time) ;
+ tty->printf("\n") ;
+ break ;
+ case ATTR_SOFTWARE_RESET: /* software reset requested! */
+ if (value[0]) {
+ printf("Software Reset Requested!\n") ;
+ reset_watch_dog() ;
+// if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ;
+ wait(0.5) ;
+ reboot_edge() ;
+ }
+ break ;
+ default:
+ break ;
+ }
+ return result ;
+}
+
+/*
+ * Callback that allows ASR to request an MCU attribute be changed.
+ * You should define this function in your MCU firmware to perform application-specific actions
+ * your code must take (e.g., updating the state of the hardware),
+ * in light of the attribute value change.
+*/
+bool attributeChangeRequest(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value
+)
+{
+ int result ;
+ uint32_t timestamp = edge_time ;
+
+ ts2time(timestamp, ¤t_time) ; /* 12 us */
+// if (verbos) {
+ print_time(¤t_time) ;
+ tty->printf(" %5d ASR requested [%d] : ", attributeId, requestId) ;
+ af_print_values(requestId, attributeId, valueLen, value) ;
+// }
+
+ result = assignAttribute(requestId, attributeId, valueLen, value, true) ;
+
+// af_print_values(requestId, attributeId, valueLen, value) ;
+ return(result == afSUCCESS) ;
+}
+
+/*
+ * Application callback that allows afLib to notify that an attribute has changed.
+ * This method will be called in response to a getAttribute call from the application
+ * and whenever a ASR module attribute changes.
+ */
+void attributeUpdatedReport(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value
+)
+{
+ uint32_t timestamp = edge_time ;
+ int result ;
+
+ ts2time(timestamp, ¤t_time) ; /* 12us */
+// if (verbos) {
+ print_time(¤t_time) ;
+ tty->printf(" %5d ASR reported [%d]: ", attributeId, requestId) ;
+ af_print_values(requestId, attributeId, valueLen, value) ;
+// }
+
+ switch(attributeId) {
+ case ATTR_LED:
+ tty->printf("LED : ") ;
+ if (value[0]) {
+ tty->printf("ON\n") ;
+ } else {
+ tty->printf("OFF\n") ;
+ }
+ break ;
+ case ATTR_LINKED_TIMESTAMP:
+ set_time(valueLen, value) ; /* 68 us */
+ tty->printf("timestamp = ") ;
+ print_date_wd(¤t_time) ;
+// print_time(¤t_time) ;
+ tty->printf("\n") ;
+ break ;
+ case ATTR_WIFI_STDY_STATE:
+ gConnected = false ;
+ tty->printf("WiFi Steady State: ") ;
+ switch(value[0]) {
+ case 0: tty->printf("Not Connected\n") ; break ;
+ case 1: tty->printf("Pending\n") ; break ;
+ case 2:
+ tty->printf("Connected\n") ;
+ gConnected = true ; // the only case Connected state is OK
+ break ;
+ case 3: tty->printf("Unknown Failure\n") ; break ;
+ case 4: tty->printf("Association Failed\n") ; break ;
+ case 5: tty->printf("Handshake Failed\n") ; break ;
+ case 6: tty->printf("Echo Failed\n") ; break ;
+ case 7: tty->printf("SSID Not Found\n") ; break ;
+ case 8: tty->printf("NTP Failed\n") ; break ;
+ default: tty->printf("Unknown [%d]\n", value[0]) ; break ;
+ }
+ break ;
+ case ATTR_REBOOT_REASON:
+ tty->printf("Reboot Reason: ") ;
+ switch(value[0]) {
+ case 1: tty->printf("Reset pin asserted\n") ; break ;
+ case 2: tty->printf("Watchdog reset\n") ; break ;
+ case 4: tty->printf("Software reset\n") ; break ;
+ case 8: tty->printf("CPU Lock up\n") ; break ;
+ default: tty->printf("Unknown [%d]\n", value[0]) ; break ;
+ }
+ break ;
+ case ATTR_MCU_INTERFACE:
+ tty->printf("MCU Interface: ") ;
+ switch(value[0]) {
+ case 0: tty->printf("No MCU\n") ; break ;
+ case 1: tty->printf("SPI Slave\n") ; break ;
+ case 2: tty->printf("UART\n") ; break ;
+ default: tty->printf("Unknown\n") ; break ;
+ }
+ break ;
+ case AF_SYSTEM_ASR_STATE:
+ tty->printf("ASR state: ") ;
+ switch(value[0]) {
+ case MODULE_STATE_REBOOTED:
+ gLinked = false ;
+ tty->printf("Rebooted\n") ;
+ wait_ms(100) ;
+ if (edge_mgr_status == EDGE_MGR_RUNNING) {
+ reboot_edge() ;
+ }
+ break ;
+ case MODULE_STATE_LINKED:
+ if (gLinked == false) { /* new link established */
+ result = afero->getAttribute(ATTR_LINKED_TIMESTAMP) ;
+ }
+ gLinked = true ;
+ tty->printf("Linked\n") ;
+ break ;
+ case MODULE_STATE_UPDATING:
+ gLinked = true ;
+ tty->printf("Updating\n") ;
+ break ;
+ case MOUDLE_STATE_UPDATE_READY:
+ gLinked = false ;
+ tty->printf("Update ready - rebooting\n") ;
+ while(afero->setAttribute32(AF_SYSTEM_COMMAND, MODULE_COMMAND_REBOOT) != afSUCCESS) {
+ afero->loop() ;
+ wait_us(100) ;
+ }
+ reboot_edge() ;
+ break ;
+ default:
+ break ;
+ }
+ break ;
+ default:
+ assignAttribute(requestId, attributeId, valueLen, value, false) ;
+ break ;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/af_attributes.h Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,124 @@
+#ifndef _AF_ATTRIBUTES_H_
+#define _AF_ATTRIBUTES_H_
+
+#include "mbed.h"
+#include "afLib.h"
+
+/**
+ * af_attributes.h
+ *
+ */
+
+#define ATTRIBUTE_TYPE_SINT8 2
+#define ATTRIBUTE_TYPE_SINT16 3
+#define ATTRIBUTE_TYPE_SINT32 4
+#define ATTRIBUTE_TYPE_SINT64 5
+#define ATTRIBUTE_TYPE_BOOLEAN 1
+#define ATTRIBUTE_TYPE_UTF8S 20
+#define ATTRIBUTE_TYPE_BYTES 21
+#define ATTRIBUTE_TYPE_FIXED_15_16 6
+
+#define afSUCCESS 0 // Operation completed successfully
+#define afERROR_NO_SUCH_ATTRIBUTE -1 // Request was made for unknown attribute id
+#define afERROR_BUSY -2 // Request already in progress, try again
+#define afERROR_INVALID_COMMAND -3 // Command could not be parsed
+#define afERROR_QUEUE_OVERFLOW -4 // Queue is full
+#define afERROR_QUEUE_UNDERFLOW -5 // Queue is empty
+#define afERROR_INVALID_PARAM -6 // Bad input parameter
+
+#define AF_SYSTEM_COMMAND 65012
+#define AF_SYSTEM_ASR_STATE 65013
+#define AF_SYSTEM_LINKED_TIMESTAMP 65015
+
+#define MODULE_STATE_REBOOTED 0
+#define MODULE_STATE_LINKED 1
+#define MODULE_STATE_UPDATING 2
+#define MOUDLE_STATE_UPDATE_READY 3
+
+#define MODULE_COMMAND_NONE 0
+#define MODULE_COMMAND_REBOOT 1
+
+#define ATTR_SOFTWARE_RESET 666
+#define ATTR_MCU_RESET_REASON 999
+
+#define ATTR_LED 1024
+#define ATTR_IO0 1025
+#define ATTR_IO1 1026
+#define ATTR_IO2 1028
+#define ATTR_BUTTON 1030
+#define ATTR_IO3 1031
+
+#define ATTR_BOOT_LOADER_VER 2001
+#define ATTR_BLE_STACK_VER 2002
+#define ATTR_FW_APP_VER 2003
+#define ATTR_DEVICE_DESC 2004
+#define ATTR_WIFI_VER 2006
+
+#define ATTR_OFFLINE_SCHED 59001
+#define ATTR_SECURITY_ENABLED 60000
+#define ATTR_UTC_OFFSET 65001
+#define ATTR_CONFIGURES_SSID 65004
+#define ATTR_WIFI_BARS 65005
+#define ATTR_WIFI_STDY_STATE 65006
+
+#define ATTR_COMMAND 65012
+#define ATTR_ASR_STATE 65013
+#define ATTR_LOW_BATTERY 65014
+#define ATTR_LINKED_TIMESTAMP 65015
+#define ATTR_ATTR_ACK 65018
+#define ATTR_REBOOT_REASON 65019
+#define ATTR_BLE_COMMS 65020
+#define ATTR_MCU_INTERFACE 65021
+
+#define DISPLAY_MODE_OFF 0
+#define DISPLAY_MODE_GAS 1
+#define DISPLAY_MODE_SUMMARY 2
+#define DISPLAY_MODE_CHART 3
+
+typedef struct {
+ uint16_t id ;
+ char *description ;
+ int attribute_type ;
+ int size ;
+} af_attribute_type ;
+
+/**
+ * get_af_attr
+ * @param id attribute id value to look up
+ * @returns index of the attribute in the af_attribute_type af_attr[]
+ */
+int get_af_attr(uint16_t id) ;
+
+/**
+ * print_af_error
+ * @param resultCode return value from afLib function(s)
+ */
+void print_af_error(int resultCode) ;
+
+/**
+ * Callback that allows ASR to request an MCU attribute be changed.
+ * You should define this function in your MCU firmware to perform application-specific actions
+ * your code must take (e.g., updating the state of the hardware),
+ * in light of the attribute value change.
+*/
+bool attributeChangeRequest(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value
+) ;
+
+/*
+ * Application callback that allows afLib to notify that an attribute has changed.
+ * This method will be called in response to a getAttribute call from the application
+ * and whenever a ASR module attribute changes.
+ */
+void attributeUpdatedReport(
+ const uint8_t requestId,
+ const uint16_t attributeId,
+ const uint16_t valueLen,
+ const uint8_t *value
+) ;
+
+extern afLib *afero ;
+#endif /* _AF_ATTRIBUTES_H */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/af_mgr.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,62 @@
+#include "mbed.h"
+#include "string.h"
+#include "edge_mgr.h"
+#include "edge_time.h"
+#include "edge_pin.h"
+#include "afLib.h"
+#include "af_attributes.h"
+#include "afTransport.h"
+#include "msg_types.h"
+#include "mbedSPI.h"
+#include "mbedUART.h"
+#include "af_mgr.h"
+
+#define ASR_USE_SPI 0
+#define ASR_USE_UART 1
+
+afLib *afero = 0 ;
+InterruptIn *afero_int = 0 ;
+afTransport *afero_spi = 0 ;
+afTransport *afero_uart = 0 ;
+DigitalOut *afero_reset ;
+bool gLinked = false ;
+bool gConnected = false ;
+
+void afero_isr(void)
+{
+ afero->mcuISR() ;
+}
+
+void init_aflib(void)
+{
+ afero_reset = new DigitalOut(PIN_ASR_RESET, 1) ; /* create as deasserted */
+ Serial *theLog = new Serial(USBTX, USBRX, 115200) ;
+
+#if (ASR_USE_SPI)
+tty->printf("afero is using SPI\n") ;
+ afero_spi = (afTransport*) new mbedSPI(PIN_MOSI, PIN_MISO, PIN_SCK, PIN_CS) ;
+ afero = new afLib(
+ PIN_INTR,
+ afero_isr,
+ attributeChangeRequest,
+ attributeUpdatedReport,
+ theLog, /* Stream for log */
+ (afTransport *)afero_spi ) ;
+#elif (ASR_USE_UART)
+tty->printf("afero is using UART2\n") ;
+ afero_uart = (afTransport*) new mbedUART(PIN_UART2_RX, PIN_UART2_TX, theLog) ;
+ afero = new afLib(
+ PIN_INTR,
+ 0,
+ attributeChangeRequest,
+ attributeUpdatedReport,
+ theLog, /* Stream for log */
+ (afTransport *)afero_uart ) ;
+#endif
+
+ wait(0.1) ;
+ *afero_reset = 0 ;
+ wait(0.5) ; /* required 250ms ~ time for reset */
+ *afero_reset = 1 ;
+ wait(0.5) ;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/af_utils/af_mgr.h Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,12 @@ +#ifndef _AF_MGR_H_ +#define _AF_MGR_H_ +#include "afLib.h" + +extern afLib *afero ; +extern bool gLinked ; +extern bool gConnected ; +extern bool verbos ; + +void init_aflib(void) ; + +#endif /* _AF_MGR_H_ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/edgeSerial.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,68 @@
+#include "mbed.h"
+#include "vt100.h"
+#include "edgeSerial.h"
+#include "edge_reset_mgr.h"
+extern vt100 *tty ;
+
+edgeSerial::edgeSerial(PinName txPin, PinName rxPin, int baud)
+: Serial(txPin, rxPin, baud)
+{
+ _is_peeked = false ;
+ _peeked_byte = 0 ;
+}
+
+char edgeSerial::edge_peek(void)
+{
+ _peeked_byte = getc() ;
+ _is_peeked = true ;
+ return( _peeked_byte ) ;
+}
+
+void edgeSerial::edge_read(uint8_t *buffer, int len)
+{
+ int i ;
+ if (_is_peeked) {
+ buffer[0] = _peeked_byte ;
+ _is_peeked = false ;
+#if 1
+ for (i = 1 ; i < len ; i++) {
+ buffer[i] = Serial::getc() ;
+ }
+#else
+ Serial::read(&buffer[1], len) ;
+#endif
+ } else {
+#if 1
+ for (i = 0 ; i < len ; i++) {
+ buffer[i] = Serial::getc() ;
+ }
+#else
+ Serial::read(buffer, len) ;
+#endif
+ }
+}
+
+char edgeSerial::edge_read(void)
+{
+ char c ;
+// tty->printf("edge_read\n") ;
+ if (_is_peeked) {
+ c = _peeked_byte ;
+ _is_peeked = false ;
+ } else {
+// Serial::read((uint8_t*)&c, 1) ;
+ c = Serial::getc() ;
+ }
+ return( c ) ;
+}
+
+void edgeSerial::edge_write(uint8_t *buffer, int len)
+{
+#if 1
+ for (int i = 0 ; i < len ; i++ ) {
+ Serial::write(&buffer[i], 1) ;
+ }
+#else
+ Serial::write(buffer, len) ;
+#endif
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/edgeSerial.h Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,20 @@
+#ifndef _EDGESERIAL_H_
+#define _EDGESERIAL_H_
+
+#include "mbed.h"
+
+class edgeSerial : public Serial {
+public:
+ edgeSerial(PinName txPin, PinName rxPin, int baud) ;
+
+ bool edge_available(void) { return Serial::readable() ; }
+ char edge_peek(void) ;
+ char edge_read(void) ;
+ void edge_read(uint8_t *buffer, int len) ;
+ void edge_write(uint8_t *buffer, int len) ;
+private:
+ bool _is_peeked ;
+ uint8_t _peeked_byte ;
+} ;
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/mbedSPI.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,215 @@
+#include "mbed.h"
+#include "afSPI.h"
+#include "mbedSPI.h"
+#include "afErrors.h"
+#include "msg_types.h"
+#include "vt100.h"
+extern vt100 *tty ;
+
+#if defined (TARGET_KL25Z) || defined (TARGET_TEENSY3_1)
+ #ifndef SPI0_C1
+ #define SPI0_C1 (*(uint8_t *)0x40076000)
+ #endif
+#endif
+
+mbedSPI::mbedSPI(PinName mosi, PinName miso, PinName sckl, PinName cs) :
+ _spi(mosi, miso, sckl), _cs(cs, 1)
+{
+ _spi.format(8, 0) ;
+ _spi.frequency(1000000) ; /* 1MHz */
+
+#if defined (TARGET_KL25Z) || defined (TARGET_TEENSY3_1)
+ #ifndef SPI0_C1
+ #define SPI0_C1 (*(uint8_t *)0x40076000)
+ #endif
+// SPI0_C1 |= 0x01 ; /* LSB First */
+// SPI0_C1 &= 0xFE ; /* MSB First */
+#endif
+
+}
+
+void mbedSPI::begin(void)
+{
+}
+
+void mbedSPI::beginSPI(void)
+{
+ _cs = 0 ;
+ SPI0_C1 |= 0x01 ; /* LSB First */
+ wait_us(8) ;
+}
+
+void mbedSPI::endSPI(void)
+{
+ _cs = 1 ;
+ SPI0_C1 &= 0xFE ; /* MSB First */
+ wait_us(1) ;
+ // SPI.endTransaction() // in the original code
+}
+
+/**
+ * on 17-Jan-2018 disable/enable irq added
+ * before and after of each _spi.writes
+ */
+void mbedSPI::transfer(char *bytes, int len)
+{
+ int i ;
+ for (i = 0 ; i < len ; i++ ) {
+ __disable_irq() ; // Disable Interrupts
+ bytes[i] = _spi.write(bytes[i]) ;
+ __enable_irq() ; // Enable Interrupts
+ }
+}
+
+void mbedSPI::checkForInterrupt(volatile int *interrupts_pending, bool idle)
+{
+ // Nothing required here.
+}
+
+int mbedSPI::exchangeStatus(StatusCommand *tx, StatusCommand *rx)
+{
+ int result = afSUCCESS ;
+ uint16_t len = tx->getSize() ;
+ int *bytes ;
+ char *rbytes ;
+ int index = 0 ;
+ bytes = new int[len] ;
+ rbytes = new char[len + 1] ;
+ tx->getBytes(bytes) ;
+
+ beginSPI() ;
+ for (int i = 0 ; i < len ; i++ ) {
+ rbytes[i] = bytes[i] ;
+ }
+ rbytes[len] = tx->getChecksum() ;
+ transfer(rbytes, len + 1) ;
+
+ uint8_t cmd = bytes[index++] ;
+ if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
+ tty->printf("exchangeStatus bad cmd: %02X\n", cmd) ;
+ result = afERROR_INVALID_COMMAND ;
+ }
+
+ rx->setBytesToSend(rbytes[index + 0] | (rbytes[index + 1] << 8)) ;
+ rx->setBytesToRecv(rbytes[index + 2] | (rbytes[index + 3] << 8)) ;
+ rx->setChecksum(rbytes[index | 4]);
+
+ endSPI() ;
+
+ delete [] bytes ;
+ delete [] rbytes ;
+ return result ;
+}
+
+int mbedSPI::writeStatus(StatusCommand *c)
+{
+ int result = afSUCCESS ;
+ uint16_t len = c->getSize() ;
+ int *bytes ;
+ char *rbytes ;
+ int index = 0 ;
+ bytes = new int[len] ;
+ rbytes = new char[len+1] ;
+ c->getBytes(bytes) ;
+
+ beginSPI() ;
+
+ for (int i = 0 ; i < len ; i++ ) {
+ rbytes[i] = bytes[i] ;
+ }
+ rbytes[len] = c->getChecksum() ;
+ transfer(rbytes, len + 1) ;
+
+ uint8_t cmd = rbytes[index++] ;
+ if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
+ tty->printf("writeStatus bad cmd: %02X\n", cmd) ;
+ result = afERROR_INVALID_COMMAND ;
+ }
+
+ endSPI() ;
+
+ delete [] rbytes ;
+ delete [] bytes ;
+
+ return result ;
+}
+
+void mbedSPI::sendBytes(char *bytes, int len)
+{
+ beginSPI() ;
+
+ transfer(bytes, len) ;
+
+ endSPI() ;
+}
+
+void mbedSPI::recvBytes(char *bytes, int len)
+{
+ beginSPI() ;
+
+ transfer(bytes, len) ;
+
+ endSPI() ;
+}
+
+void mbedSPI::sendBytesOffset(char *bytes, uint16_t *bytesToSend, uint16_t *offset)
+{
+ uint16_t len = 0;
+
+ len = *bytesToSend > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToSend;
+
+ char *buffer ;
+ buffer = new char[len] ;
+ memset(buffer, 0xff, sizeof(buffer));
+
+ memcpy(buffer, &bytes[*offset], len);
+
+ sendBytes(buffer, len);
+
+ *offset += len;
+ *bytesToSend -= len;
+
+ delete [] buffer ;
+}
+
+#if 1
+void mbedSPI::recvBytesOffset(char **bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset)
+{
+ uint16_t len = 0;
+
+ len = *bytesToRecv > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToRecv;
+
+ if (*offset == 0) {
+ *bytesLen = *bytesToRecv;
+ *bytes = new char[*bytesLen];
+ }
+
+ char *start = *bytes + *offset;
+
+ recvBytes(start, len);
+
+ *offset += len;
+ *bytesToRecv -= len;
+}
+#endif
+
+#if 0
+void mbedSPI::recvBytesOffset(char *bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset)
+{
+ uint16_t len = 0;
+
+ len = *bytesToRecv > SPI_FRAME_LEN ? SPI_FRAME_LEN : *bytesToRecv;
+
+ if (*offset == 0) {
+ *bytesLen = *bytesToRecv;
+// *bytes = new char[*bytesLen];
+ }
+
+ char *start = bytes + *offset;
+
+ recvBytes(start, len);
+
+ *offset += len;
+ *bytesToRecv -= len;
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/mbedSPI.h Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,38 @@
+/**
+ * mbedSPI
+ *
+ * mbed spi class for afero afLib.
+ */
+#ifndef _MBEDSPI_H_
+#define _MBEDSPI_H_
+#include "mbed.h"
+#include "afSPI.h"
+#include "StatusCommand.h"
+#include "afTransport.h"
+
+#define SPI_FRAME_LEN ((uint16_t)16)
+
+class mbedSPI : public afTransport {
+public:
+ mbedSPI(PinName mosi, PinName miso, PinName sckl, PinName cs) ;
+
+ virtual void checkForInterrupt(volatile int *interrupts_pending, bool idle);
+ virtual int exchangeStatus(StatusCommand *tx, StatusCommand *rx);
+ virtual int writeStatus(StatusCommand *c);
+ virtual void sendBytes(char *bytes, int len);
+ virtual void recvBytes(char *bytes, int len);
+ virtual void sendBytesOffset(char *bytes, uint16_t *bytesToSend, uint16_t *offset);
+ virtual void recvBytesOffset(char **bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset);
+// virtual void recvBytesOffset(char *bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset);
+private:
+ virtual void begin(void) ;
+ virtual void beginSPI(void) ;
+ virtual void endSPI(void) ;
+ virtual void transfer(char *bytes,int len) ;
+
+ SPI _spi ;
+ DigitalOut _cs ;
+} ;
+
+
+#endif /* _MBEDSPI_H_ */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/mbedUART.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,215 @@
+#include "mbed.h"
+#include "afErrors.h"
+#include "msg_types.h"
+#include "mbedUART.h"
+#include "edge_mgr.h"
+#include "edge_reset_mgr.h"
+
+#define mbedUART_BUFSIZE 300
+
+mbedUART::mbedUART(PinName rxPin, PinName txPin, Serial *theLog)
+{
+ _uart = new edgeSerial(txPin, rxPin, 9600) ;
+ _buf = new uint8_t[300] ;
+}
+
+mbedUART::~mbedUART(void)
+{
+ if (_buf) {
+ delete [] _buf ;
+ }
+}
+
+int mbedUART::available(void)
+{
+ return (int)_uart->readable() ;
+}
+
+char mbedUART::peek(void)
+{
+ char c ;
+ c = _uart->edge_peek() ;
+// c = _uart->getc() ;
+ return c ;
+
+// return _uart->peek() ;
+}
+
+void mbedUART::read(uint8_t *buffer, int len)
+{
+ _uart->edge_read(buffer, len) ;
+}
+
+char mbedUART::read(void)
+{
+ char c ;
+ c = _uart->edge_read() ;
+ return( c ) ;
+}
+
+void mbedUART::write(uint8_t *buffer, int len)
+{
+ _uart->edge_write(buffer, len) ;
+}
+
+void mbedUART::checkForInterrupt(volatile int *interrupts_pending, bool idle)
+{
+ char c ;
+ if (_uart->readable()) {
+ c = _uart->edge_peek() ;
+//tty->printf("Char %02X received\n", c) ;
+ if (c == INT_CHAR) {
+ if (*interrupts_pending == 0) {
+ c = _uart->edge_read() ;
+ *interrupts_pending += 1 ; /* (*interrupts_pending)++ ; */
+ } else if (idle) {
+ c = _uart->edge_read() ;
+ } else {
+ // _theLog->printf("INT(Pending)\n") ;
+ }
+ } else {
+ if (*interrupts_pending == 0) {
+ c = _uart->edge_read() ;
+ }
+ }
+ }
+}
+
+int mbedUART::exchangeStatus(StatusCommand *tx, StatusCommand *rx)
+{
+ int result = afSUCCESS ;
+ int i ;
+ uint16_t len ;
+ int *bytes ;
+ char *rbytes ;
+ int index = 0 ;
+ len = tx->getSize() ;
+ bytes = new int[len] ;
+ rbytes = new char[len + 1] ;
+ tx->getBytes(bytes) ;
+
+ for(i = 0 ; i < len ; i++ ) {
+ rbytes[i] = bytes[i] ;
+ }
+ rbytes[len] = tx->getChecksum() ;
+ sendBytes(rbytes, len + 1) ;
+
+ // Skip any interrupts, that may have come in.
+ do {
+ recvBytes(rbytes, 1) ;
+ } while(rbytes[0] == INT_CHAR) ;
+
+ // Okay, we have good first char, now read the rest
+ recvBytes(&rbytes[1], len) ;
+
+ uint8_t cmd = bytes[index++] ;
+ if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
+ tty->printf("exchangeStatus bad cmd: %02X\n", cmd) ;
+ result = afERROR_INVALID_COMMAND ;
+ }
+
+ rx->setBytesToSend(rbytes[index + 0] | (rbytes[index + 1] << 8)) ;
+ rx->setBytesToRecv(rbytes[index + 2] | (rbytes[index + 3] << 8)) ;
+ rx->setChecksum(rbytes[index + 4]) ;
+
+ delete [] rbytes ;
+ delete [] bytes ;
+ return result ;
+}
+
+
+int mbedUART::writeStatus(StatusCommand *c)
+{
+ int result = afSUCCESS ;
+ uint16_t len ;
+ int *bytes ;
+ char *rbytes ;
+ int index = 0 ;
+ len = c->getSize() ;
+ bytes = new int[len] ;
+ rbytes = new char[len + 1] ;
+
+ c->getBytes(bytes) ;
+ for (int i = 0 ; i < len ; i++ ) {
+ rbytes[i] = bytes[i] ;
+ }
+ rbytes[len] = c->getChecksum() ;
+
+ sendBytes(rbytes, len + 1) ;
+
+ uint8_t cmd = rbytes[index++] ;
+ if (cmd != SYNC_REQUEST && cmd != SYNC_ACK) {
+ tty->printf("writeStatus bad cmd: %02X\n", cmd) ;
+ result = afERROR_INVALID_COMMAND ;
+ }
+ // c->dump() ;
+ // c->dumpBytes() ;
+
+ delete [] rbytes ;
+ delete [] bytes ;
+
+ return result ;
+}
+
+void mbedUART::sendBytes(char *bytes, int len)
+{
+#if 0
+tty->printf("sendBytes %d: ", len) ;
+for (int i = 0 ; i < len ; i++ ) { tty->printf("%02X ", bytes[i]) ; }
+tty->printf("\n") ;
+#endif
+
+ _uart->edge_write((uint8_t *)bytes, len) ;
+}
+
+void mbedUART::recvBytes(char *bytes, int len)
+{
+ _uart->edge_read((uint8_t *)bytes, len) ;
+
+#if 0
+tty->printf("recvBytes %d: ", len) ;
+for (int i = 0 ; i < len ; i++ ) { tty->printf("%02X ", bytes[i]) ; }
+tty->printf("\n") ;
+#endif
+}
+
+void mbedUART::sendBytesOffset(char *bytes, uint16_t *bytesToSend, uint16_t *offset)
+{
+ uint16_t len = 0 ;
+
+ len = *bytesToSend ;
+
+// sendBytes(bytes, len) ;
+ sendBytes(&bytes[*offset], len) ;
+
+ // dumpBytes("Sending: ", len, bytes) ;
+
+ *offset += len ;
+ *bytesToSend -= len ;
+}
+
+void mbedUART::recvBytesOffset(char **bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset)
+{
+ uint16_t len = 0 ;
+
+ len = *bytesToRecv ;
+
+ if (*offset == 0) {
+ *bytesLen = *bytesToRecv ;
+ *bytes = new char[*bytesLen] ;
+ }
+
+ char * start = *bytes + *offset ;
+
+ recvBytes(start, len) ;
+
+// dumpBytes("Receiving:", len, _readBuffer) ;
+#if 0
+ tty->printf("Receiving: ") ;
+ for (int i = 0; i < len ; i++ ) { tty->printf("%02X ", start[i]) ; }
+ tty->printf("\n") ;
+#endif
+
+ *offset += len ;
+ *bytesToRecv -= len ;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/mbedUART.h Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,35 @@
+#ifndef _MBEDUART_H_
+#define _MBEDUART_H_
+#include "mbed.h"
+#include "afTransport.h"
+#include "edgeSerial.h"
+
+#define INT_CHAR 0x32
+
+class mbedUART : public afTransport {
+public:
+ mbedUART(PinName rxPin, PinName txPin, Serial *theLog) ;
+ ~mbedUART(void) ;
+
+ virtual void checkForInterrupt(volatile int *interrupts_pending, bool idle);
+ virtual int exchangeStatus(StatusCommand *tx, StatusCommand *rx);
+ virtual int writeStatus(StatusCommand *c);
+ virtual void sendBytes(char *bytes, int len);
+ virtual void recvBytes(char *bytes, int len);
+ virtual void sendBytesOffset(char *bytes, uint16_t *bytesToSend, uint16_t *offset);
+ virtual void recvBytesOffset(char **bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset);
+// virtual void recvBytesOffset(char *bytes, uint16_t *bytesLen, uint16_t *bytesToRecv, uint16_t *offset);
+private:
+ edgeSerial *_uart ;
+// Serial *_uart ;
+// Stream *_uart ;
+ Serial *_theLog ;
+ uint8_t *_buf ;
+
+ int available(void);
+ char peek(void);
+ void read(uint8_t *buffer, int len);
+ char read(void);
+ void write(uint8_t *buffer, int len);
+};
+#endif /* _MBEDUART_H_ */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_utils/edge_mgr.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,41 @@
+#include "mbed.h"
+#include "edge_mgr.h"
+#include "edge_reset_mgr.h"
+#include "af_attributes.h"
+
+#include "edge_time.h"
+#include "edge_pin.h"
+
+bool verbos = true ;
+
+static int error_tolerance = 100 ;
+static int loop_interval = 100 ; // 1000 ;
+int edge_mgr_status = EDGE_MGR_INIT ;
+char *reset_reason_str = 0 ;
+
+int init_edge_attribute(void)
+{
+ static int attr_index = 0 ;
+ static int error_count = 0 ;
+ int return_value = 0 ;
+ int result ;
+
+
+ if (error_count > error_tolerance) { // too many fails, trying reset
+ reboot_edge() ;
+ }
+
+ return(return_value) ;
+}
+
+void edge_loop(uint32_t count_robin)
+{
+ if ((count_robin % loop_interval) == 0) {
+ loop_interval = 1 ;
+ }
+}
+
+void reboot_edge(void)
+{
+ software_reset() ;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_mgr.h Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,18 @@ +#ifndef _EDGE_MGR_H_ +#define _EDGE_MGR_H_ +#include "mbed.h" +#include "vt100.h" + +int init_edge_attribute(void) ; +void edge_loop(uint32_t tick_count) ; +void reboot_edge(void) ; + +extern char *reset_reason_str ; +extern bool verbos ; +extern int edge_mgr_status ; +extern vt100 *tty ; + +#define EDGE_MGR_INIT 0 +#define EDGE_MGR_RUNNING 1 + +#endif /* _EDGE_MGR_H_ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_pin.h Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,39 @@ +#ifndef _EDGE_PIN_H_ +#define _EDGE_PIN_H_ + +#if defined (TARGET_KL25Z) +#define PIN_INTR PTD4 +#define PIN_ASR_RESET PTA13 +#define PIN_SCK PTD1 +#define PIN_MOSI PTD2 +#define PIN_MISO PTD3 +#define PIN_CS PTD0 +/* ILI9341 */ +#define PIN_CS_TFT PTC7 +#define PIN_RESET_TFT PTC4 +#define PIN_DC_TFT PTC0 +#define PIN_BL_TFT PTC3 + +#define PIN_FRDM_LEDR PTB18 +#define PIN_FRDM_LEDG PTB19 +#define PIN_FRDM_LEDB PTD1 /* conflict with SCK orz */ +/* on board I2C0 */ +// #define PIN_I2C0_SCL PTE24 +// #define PIN_I2C0_SDA PTE25 +/* external I2C0 */ +#define PIN_I2C0_SCL PTC8 +#define PIN_I2C0_SDA PTC9 +#define PIN_I2C1_SCL PTE1 +#define PIN_I2C1_SDA PTE0 +#define PIN_AN0 PTB0 +#define PIN_AN1 PTB1 +#define PIN_AN2 PTB2 +#define PIN_LED_R PTB18 +#define PIN_LED_G PTB19 +#define PIN_LED_B PTD1 + +#define PIN_UART2_TX PTE22 +#define PIN_UART2_RX PTE23 +#endif /* TARGET_KL25Z */ + +#endif /* _EDGE_PIN_H_ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_utils/edge_reset_mgr.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,146 @@
+#include "mbed.h"
+#include "edge_mgr.h"
+#include "edge_reset_mgr.h"
+
+/**
+ * System Reset Status Register 0 (RCM_SRS0) 0x4007_F000
+ *
+ * bit[7] : POR Power-On Reset
+ * bit[6] : PIN External Reset Pin
+ * bit[5] : WDOG Watchdog
+ * bit[4] : (Reserved)
+ * bit[3] : LOL Loss-of-Lock Reset
+ * bit[2] : LOC Loss-of-Clock Reset
+ * bit[1] : LVD Low-Voltage Detect Reset
+ * bit[0] : WAKEUP Low Leakage Wakeup Reset
+ */
+#define REG_RCM_SRS0 (uint8_t *)0x4007F000
+#define POR_RESET_BIT 0x80
+#define PIN_RESET_BIT 0x40
+#define WDG_RESET_BIT 0x20
+#define LOL_RESET_BIT 0x08
+#define LOC_RESET_BIT 0x04
+#define LVD_RESET_BIT 0x02
+#define WUP_RESET_BIT 0x01
+
+ /**
+ * System Reset Status Register 1 (RCM_SRS1) 0x4007_F001
+ *
+ * bit[7:6] (Reserved)
+ * bit[5] : SACKERR Stop Mode Acknowledge Error Reset
+ * bit[4] : (Reserved)
+ * bit[3] : MDM_AP MDM-AP System Reset Request
+ * bit[2] : SW Software Reset
+ * bit[1] : LOCKUP Core Lockup
+ * bit[0] : (Reserved)
+ */
+#define REG_RCM_SRS1 (uint8_t *)0x4007F001
+#define SACK_RESET_BIT 0x20
+#define MDM_RESET_BIT 0x08
+#define SW_RESET_BIT 0x04
+#define LOCKUP_RESET_BIT 0x02
+
+#define IDX_POR_RESET 0
+#define IDX_PIN_RESET 1
+#define IDX_WDG_RESET 2
+#define IDX_LOL_RESET 3
+#define IDX_LOC_RESET 4
+#define IDX_LVD_RESET 5
+#define IDX_WUP_RESET 6
+#define IDX_SACK_RESET 7
+#define IDX_MDM_RESET 8
+#define IDX_SW_RESET 9
+#define IDX_LOCKUP_RESET 10
+
+const char *reset_reason[] = {
+ "Power On Reset",
+ "Reset Pin Asserted",
+ "Watch Dog Reset",
+ "Loss of Lock Reset",
+ "Loss of Clock Reset",
+ "Low Voltage Detect Reset",
+ "Low Leakage Wakeup Reset",
+ "Stop Mode Acknowledge Error Reset",
+ "MDM-AP System Reset Request",
+ "Software Reset",
+ "Core Lockup Reset",
+ 0
+} ;
+
+void print_reset_reason(void)
+{
+ extern char *reset_reason_str ;
+ int idx = 0 ;
+ uint8_t *data = REG_RCM_SRS0 ;
+ if (*data & POR_RESET_BIT) {
+ idx = IDX_POR_RESET ;
+ }
+ if (*data & PIN_RESET_BIT) {
+ idx = IDX_PIN_RESET ;
+ }
+ if (*data & WDG_RESET_BIT) {
+ idx = IDX_WDG_RESET ;
+ }
+ if (*data & LOL_RESET_BIT) {
+ idx = IDX_LOL_RESET ;
+ }
+ if (*data & LVD_RESET_BIT) {
+ idx = IDX_LVD_RESET ;
+ }
+ if (*data & LOC_RESET_BIT) {
+ idx = IDX_LOC_RESET ;
+ }
+ if (*data & WUP_RESET_BIT) {
+ idx = IDX_WUP_RESET ;
+ }
+ data = REG_RCM_SRS1 ;
+ if (*data & SACK_RESET_BIT) {
+ idx = IDX_SACK_RESET ;
+ }
+ if (*data & MDM_RESET_BIT) {
+ idx = IDX_MDM_RESET ;
+ }
+ if (*data & SW_RESET_BIT) {
+ idx = IDX_SW_RESET ;
+ }
+ if (*data & LOCKUP_RESET_BIT) {
+ idx = IDX_LOCKUP_RESET ;
+ }
+ tty->printf("%s\n", reset_reason[idx]) ;
+ reset_reason_str = (char *)reset_reason[idx] ;
+}
+
+/**
+ * Software Reset
+ *
+ * From Cortex-M0 Devices Generic User Guide
+ * 4.3.4 Application Interrupt and Reset Control Register
+ *
+ * Bit[31:16] : VECTCKEY
+ * Bit[15] : ENDIANESS
+ * Bit[14:3] : (Reserved)
+ * Bit[2] : SYSRESETREQ
+ * Bit[1] : VECTCLRACTIVE (reserved for debug use)
+ * Bit[0] : (Reserved)
+ *
+ * Note: To trigger software reset, both VECTKEY=0x05FA and SYSRESETREQ
+ * must be written at once, therefore the value will be
+ * 0x05FA0004
+ */
+
+void software_reset(void)
+{
+ SCB->AIRCR = 0x05FA0004 ;
+}
+
+/**
+ * reset_watch_dog
+ * reset the watch dog counter
+ * this function must be called within the limit (1sec)
+ */
+
+void reset_watch_dog(void)
+{
+ SIM->SRVCOP = (uint32_t)0x55u;
+ SIM->SRVCOP = (uint32_t)0xAAu;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_reset_mgr.h Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,8 @@ +#ifndef _EDGE_RESET_MGR_H_ +#define _EDGE_RESET_MGR_H_ + +void print_reset_reason(void) ; +void software_reset(void) ; +void reset_watch_dog(void) ; + +#endif /* _EDGE_RESET_MGR_H_ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_utils/edge_time.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,231 @@
+#include "mbed.h"
+#include "edge_mgr.h"
+#include "edge_time.h"
+
+static const uint8_t daysInMonth[12] = {
+ 31, 28, 31, 30,
+ 31, 30, 31, 31,
+ 30, 31, 30, 31
+} ;
+
+const char *nameOfDay[7] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday"
+} ;
+
+uint32_t edge_time = 0 ;
+uint32_t utc_offset = 9 * 60 * 60 ;
+tm current_time ;
+Ticker *tokei = 0 ;
+
+void inc_sec(void)
+{
+ __disable_irq() ; // Disable Interrupts
+ edge_time++ ;
+ __enable_irq() ; // Enable Interrupts
+}
+
+void init_timer(void)
+{
+ tokei = new Ticker() ;
+ tokei->attach(inc_sec, 1.0) ;
+}
+
+void set_time(const uint16_t valueLen, const uint8_t *value)
+{
+ uint32_t tmp_timestamp = 0 ;
+ for (int i = 0 ; i < valueLen ; i++ ) {
+ tmp_timestamp |= (value[i] & 0xFF) << (i * 8) ;
+ }
+ edge_time = tmp_timestamp ;
+ ts2tm(edge_time, ¤t_time) ;
+// ts2time(edge_time, ¤t_time) ;
+}
+
+void ts2time(uint32_t timestamp, struct tm *tm)
+{
+ uint32_t seconds, minutes, hours, days, month, year ;
+ uint32_t dayOfWeek ;
+
+// timestamp += (3600 * 9) ; /* +9 hours for JST */
+ timestamp += utc_offset ;
+
+ seconds = timestamp % 60 ;
+ minutes = timestamp / 60 ;
+ hours = minutes / 60 ; /* +9 for JST */
+ minutes -= hours * 60 ;
+ days = hours / 24 ;
+ hours -= days * 24 ;
+
+ tm->tm_sec = seconds ;
+ tm->tm_min = minutes ;
+ tm->tm_hour = hours ;
+ tm->tm_mday = days + 1 ;
+// tm->tm_mon = month ;
+// tm->tm_year = year ;
+// tm->tm_wday = dayOfWeek ;
+}
+
+void ts2tm(uint32_t timestamp, struct tm *tm)
+{
+ uint32_t seconds, minutes, hours, days, month, year ;
+ uint32_t dayOfWeek ;
+
+// timestamp += (3600 * 9) ; /* +9 hours for JST */
+ timestamp += utc_offset ;
+
+ seconds = timestamp % 60 ;
+ minutes = timestamp / 60 ;
+ hours = minutes / 60 ; /* +9 for JST */
+ minutes -= hours * 60 ;
+ days = hours / 24 ;
+ hours -= days * 24 ;
+
+ /* Unix timestamp start 1-Jan-1970 Thursday */
+ year = 1970 ;
+ dayOfWeek = 4 ; /* Thursday */
+
+ while(1) {
+ bool isLeapYear =
+ (((year % 4) == 0)
+ &&(((year % 100) != 0)
+ || ((year % 400) == 0))) ;
+ uint16_t daysInYear = isLeapYear ? 366 : 365 ;
+ if (days >= daysInYear) {
+ dayOfWeek += isLeapYear ? 2 : 1 ;
+ days -= daysInYear ;
+ if (dayOfWeek >= 7) {
+ dayOfWeek -= 7 ;
+ }
+ year++ ;
+ } else {
+ tm->tm_yday = days ;
+ dayOfWeek += days ;
+ dayOfWeek %= 7 ;
+
+ /* calc the month and the day */
+ for (month = 0 ; month < 12 ; month++) {
+ uint8_t dim = daysInMonth[month] ;
+
+ /* add a day to feburary if this is a leap year */
+ if ((month == 1) && (isLeapYear)) {
+ dim++ ;
+ }
+
+ if (days >= dim) {
+ days -= dim ;
+ } else {
+ break ;
+ }
+ }
+ break ;
+ }
+ }
+ tm->tm_sec = seconds ;
+ tm->tm_min = minutes ;
+ tm->tm_hour = hours ;
+ tm->tm_mday = days + 1 ;
+ tm->tm_mon = month ;
+ tm->tm_year = year ;
+ tm->tm_wday = dayOfWeek ;
+}
+
+void print_time(struct tm *tm)
+{
+ tty->printf("%02d:%02d:%02d",
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec ) ;
+}
+
+void print_time(uint32_t thetime)
+{
+ struct tm timestruct ;
+ ts2time(thetime, ×truct) ;
+ print_time(×truct) ;
+}
+
+void print_time(void)
+{
+ struct tm timestruct ;
+ ts2time(edge_time, ×truct) ;
+ print_time(×truct) ;
+}
+
+void print_date(struct tm *tm)
+{
+ tty->printf("%d/%d/%d %02d:%02d:%02d",
+ tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec
+ ) ;
+}
+
+void print_date_wd(struct tm *tm)
+{
+ tty->printf("%d/%d/%d %02d:%02d:%02d (%s)",
+ tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ nameOfDay[tm->tm_wday]
+ ) ;
+}
+
+void time2str(struct tm *tm, char *timestr)
+{
+ sprintf(timestr, "%02d:%02d:%02d",
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec ) ;
+}
+
+void time2str(char *timestr)
+{
+ struct tm timestruct ;
+ ts2time(edge_time, ×truct) ;
+ time2str(×truct, timestr) ;
+}
+
+int32_t time2seq(uint32_t timestamp)
+{
+ struct tm timestruct ;
+ int32_t result ;
+ ts2time(timestamp, ×truct) ;
+ result = timestruct.tm_hour * 10000
+ + timestruct.tm_min * 100
+ + timestruct.tm_sec ;
+ return(result) ;
+}
+
+void time2seq(uint32_t timestamp, char *timestr)
+{
+ struct tm timestruct ;
+ ts2tm(timestamp, ×truct) ;
+ sprintf(timestr, "%d%02d%02d%02d%02d%02d",
+ timestruct.tm_year,
+ timestruct.tm_mon + 1,
+ timestruct.tm_mday,
+ timestruct.tm_hour,
+ timestruct.tm_min,
+ timestruct.tm_sec
+ ) ;
+}
+
+void time2date(struct tm *tm, char *datestr)
+{
+ sprintf(datestr, "%d/%d/%d %02d:%02d:%02d (%s)",
+ tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ nameOfDay[tm->tm_wday]
+ ) ;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_time.h Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,25 @@ +#ifndef _EDGE_TIME_H_ +#define _EDGE_TIME_H_ +#include "mbed.h" + +void init_timer(void) ; +void set_time(const uint16_t valueLen, const uint8_t *value) ; +void ts2time(uint32_t timestamp, struct tm *tm) ; /* light version */ +void ts2tm(uint32_t timestamp, struct tm *date) ; /* full version */ +void print_time(void) ; /* light version */ +void print_time(uint32_t thetime) ; +void print_time(struct tm *tm) ; /* light version */ +void print_date(struct tm *date) ; /* full version */ +void print_date_wd(struct tm *date) ; /* vull version with day of week */ +void time2str(char *timestr) ; /* light version */ +int32_t time2seq(uint32_t timestamp) ; /* hhmmss */ +void time2seq(uint32_t timestamp, char *timestr) ; +void time2str(struct tm *tm, char *timestr) ; /* hh:mm:ss */ +void time2date(struct tm *tm, char *datestr) ; /* YYYY/MM/DD hh:mm:ss */ +void time2date(struct tm *tm, char *datestr) ; /* full version with day of week */ + +extern const char *nameOfDay[] ; +extern tm current_time ; +extern uint32_t edge_time ; +extern uint32_t utc_offset ; +#endif /* _EDGE_TIME_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Apr 23 06:15:26 2018 +0000
@@ -0,0 +1,120 @@
+#include "mbed.h"
+#include "vt100.h"
+
+#include "af_mgr.h"
+#include "af_attributes.h"
+#include "edge_mgr.h"
+#include "edge_pin.h"
+#include "edge_time.h"
+#include "edge_reset_mgr.h"
+
+vt100 *tty = 0 ;
+uint32_t wait_tolerance = 500 ; /* 5sec */
+uint32_t connect_tolerance = 60 ; /* after 60 trials, reboot */
+uint32_t wait_count = 0 ;
+uint32_t connect_trial_count = 0 ;
+
+DigitalOut *led_r = 0 ;
+DigitalOut *led_g = 0 ;
+DigitalOut *led_b = 0 ;
+// DigitalOut myled(LED1);
+
+void doLEDs(int num)
+{
+ if (num & 0x01) { *led_b = 0 ; } else { *led_b = 1 ; }
+ if (num & 0x02) { *led_g = 0 ; } else { *led_g = 1 ; }
+ if (num & 0x04) { *led_r = 0 ; } else { *led_r = 1 ; }
+}
+
+/**
+ * wait_connection
+ * When gConnected == false, which is connection is lost.
+ * Each 5sec check attribute ATTR_WIFI_STDY_STATE to see
+ * if the connection has recovered.
+ * Meantime even if connection is established communicated
+ * data is invalid, so AF_SYSTEM_ASR_STATE is also
+ * checked for gLinked ;
+ * And in case connect_tolerance trials failed
+ * try to reboot the system if it can improve the situation.
+ */
+void wait_connection(void)
+{
+ int result ;
+ wait_count++ ;
+ if (wait_count > wait_tolerance) {
+ if (gConnected == false) {
+ result = afero->getAttribute(ATTR_WIFI_STDY_STATE) ;
+ if (result != afSUCCESS) {
+ print_af_error(result) ;
+ }
+ }
+ if (gLinked == false) {
+ result = afero->getAttribute(AF_SYSTEM_ASR_STATE) ;
+ if (result != afSUCCESS) {
+ print_af_error(result) ;
+ }
+ }
+ connect_trial_count++ ;
+ if (connect_trial_count > connect_tolerance) {
+ reboot_edge() ;
+ }
+ wait_count = 0 ;
+ }
+}
+
+void init_hardware(void)
+{
+ tty = new vt100(PTA2, PTA1, 115200) ;
+// tty->cls() ;
+ led_r = new DigitalOut(PIN_LED_R, 1) ;
+ led_g = new DigitalOut(PIN_LED_G, 1) ;
+ led_b = new DigitalOut(PIN_LED_B, 1) ;
+}
+
+#if 1
+int main()
+{
+ int led_state = 0 ;
+ init_hardware() ;
+ tty->printf("afLib1.3 UART test program (%s)\n", __DATE__) ;
+ tty->printf("Reset Reason: ") ;
+ print_reset_reason() ;
+ init_aflib() ;
+ tty->printf("afLib 1.3 initialized\n") ;
+ doLEDs(0x04) ;
+ init_timer() ;
+ tty->printf("timer init done\n") ;
+ while(1) {
+ afero->loop() ;
+ if (afero->isIdle()) {
+ led_state = 0x04 ; /* red */
+ if (gLinked && gConnected) {
+ led_state = 0x02 ; /* green */
+ } else if (gConnected) {
+ led_state = 0x01 ; /* blue */
+ } else {
+ wait_connection() ;
+ }
+ doLEDs(led_state) ;
+ wait_ms(100);
+ }
+ }
+}
+#else
+int main()
+{
+ init_hardware() ;
+ tty->printf("afLib1.3 test program (%s)\n", __DATE__) ;
+ init_aflib() ;
+ tty->printf("afLib 1.3 initialized\n") ;
+ init_timer() ;
+ tty->printf("timer init done\n") ;
+ while(1) {
+ afero->loop() ;
+ if (afero->isIdle()) {
+ *led_r = ! (*led_r) ;
+ wait_ms(100);
+ }
+ }
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/7130f322cb7e \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vt100.lib Mon Apr 23 06:15:26 2018 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Rhyme/code/vt100/#141a8a98c504