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