ECE 4180 Project for Spring 2020
Dependencies: mbed mbed-rtos SDFileSystem PinDetect ESP8266NodeMCUInterface
Revision 0:b97c07227845, committed 2020-04-30
- Comitter:
- kimberlylie99
- Date:
- Thu Apr 30 00:27:23 2020 +0000
- Child:
- 1:5ae291085f75
- Commit message:
- ECE4180 Your Fitness Pal;
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP8266NodeMCUInterface.lib Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/ESP8266/code/ESP8266NodeMCUInterface/#6031f70e3914
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HistoryCache.h Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <string>
+#include <cstring>
+#include <ctime>
+
+class HistoryCache
+{
+
+public:
+ static char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict);
+
+ static std::string getTimeStamp(time_t epochTime, const char* format = "%Y-%m-%d %H:%M:%S")
+ {
+ char timestamp[64] = {0};
+ strftime(timestamp, sizeof(timestamp), format, localtime(&epochTime));
+ return timestamp;
+ }
+
+ static time_t convertTimeToEpoch(const char* theTime, const char* format = "%Y-%m-%d %H:%M:%S")
+ {
+ std::tm tmTime;
+ memset(&tmTime, 0, sizeof(tmTime));
+ HistoryCache::strptime(theTime, format, &tmTime);
+ return mktime(&tmTime);
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.lib Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PowerControl/EthernetPowerControl.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,138 @@
+#include "EthernetPowerControl.h"
+
+static void write_PHY (unsigned int PhyReg, unsigned short Value) {
+ /* Write a data 'Value' to PHY register 'PhyReg'. */
+ unsigned int tout;
+ /* Hardware MII Management for LPC176x devices. */
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MWTD = Value;
+
+ /* Wait utill operation completed */
+ for (tout = 0; tout < MII_WR_TOUT; tout++) {
+ if ((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+ break;
+ }
+ }
+}
+
+static unsigned short read_PHY (unsigned int PhyReg) {
+ /* Read a PHY register 'PhyReg'. */
+ unsigned int tout, val;
+
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MCMD = MCMD_READ;
+
+ /* Wait until operation completed */
+ for (tout = 0; tout < MII_RD_TOUT; tout++) {
+ if ((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+ break;
+ }
+ }
+ LPC_EMAC->MCMD = 0;
+ val = LPC_EMAC->MRDD;
+
+ return (val);
+}
+
+void EMAC_Init()
+{
+ unsigned int tout,regv;
+ /* Power Up the EMAC controller. */
+ Peripheral_PowerUp(LPC1768_PCONP_PCENET);
+
+ LPC_PINCON->PINSEL2 = 0x50150105;
+ LPC_PINCON->PINSEL3 &= ~0x0000000F;
+ LPC_PINCON->PINSEL3 |= 0x00000005;
+
+ /* Reset all EMAC internal modules. */
+ LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
+ MAC1_SIM_RES | MAC1_SOFT_RES;
+ LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;
+
+ /* A short delay after reset. */
+ for (tout = 100; tout; tout--);
+
+ /* Initialize MAC control registers. */
+ LPC_EMAC->MAC1 = MAC1_PASS_ALL;
+ LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
+ LPC_EMAC->MAXF = ETH_MAX_FLEN;
+ LPC_EMAC->CLRT = CLRT_DEF;
+ LPC_EMAC->IPGR = IPGR_DEF;
+
+ /* Enable Reduced MII interface. */
+ LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;
+
+ /* Reset Reduced MII Logic. */
+ LPC_EMAC->SUPP = SUPP_RES_RMII;
+ for (tout = 100; tout; tout--);
+ LPC_EMAC->SUPP = 0;
+
+ /* Put the DP83848C in reset mode */
+ write_PHY (PHY_REG_BMCR, 0x8000);
+
+ /* Wait for hardware reset to end. */
+ for (tout = 0; tout < 0x100000; tout++) {
+ regv = read_PHY (PHY_REG_BMCR);
+ if (!(regv & 0x8000)) {
+ /* Reset complete */
+ break;
+ }
+ }
+}
+
+
+void PHY_PowerDown()
+{
+ if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
+ EMAC_Init(); //init EMAC if it is not already init'd
+
+ unsigned int regv;
+ regv = read_PHY(PHY_REG_BMCR);
+ write_PHY(PHY_REG_BMCR, regv | (1 << PHY_REG_BMCR_POWERDOWN));
+ regv = read_PHY(PHY_REG_BMCR);
+
+ //shouldn't need the EMAC now.
+ Peripheral_PowerDown(LPC1768_PCONP_PCENET);
+
+ //and turn off the PHY OSC
+ LPC_GPIO1->FIODIR |= 0x8000000;
+ LPC_GPIO1->FIOCLR = 0x8000000;
+}
+
+void PHY_PowerUp()
+{
+ if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
+ EMAC_Init(); //init EMAC if it is not already init'd
+
+ LPC_GPIO1->FIODIR |= 0x8000000;
+ LPC_GPIO1->FIOSET = 0x8000000;
+
+ //wait for osc to be stable
+ wait_ms(200);
+
+ unsigned int regv;
+ regv = read_PHY(PHY_REG_BMCR);
+ write_PHY(PHY_REG_BMCR, regv & ~(1 << PHY_REG_BMCR_POWERDOWN));
+ regv = read_PHY(PHY_REG_BMCR);
+}
+
+void PHY_EnergyDetect_Enable()
+{
+ if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
+ EMAC_Init(); //init EMAC if it is not already init'd
+
+ unsigned int regv;
+ regv = read_PHY(PHY_REG_EDCR);
+ write_PHY(PHY_REG_BMCR, regv | (1 << PHY_REG_EDCR_ENABLE));
+ regv = read_PHY(PHY_REG_EDCR);
+}
+
+void PHY_EnergyDetect_Disable()
+{
+ if (!Peripheral_GetStatus(LPC1768_PCONP_PCENET))
+ EMAC_Init(); //init EMAC if it is not already init'd
+ unsigned int regv;
+ regv = read_PHY(PHY_REG_EDCR);
+ write_PHY(PHY_REG_BMCR, regv & ~(1 << PHY_REG_EDCR_ENABLE));
+ regv = read_PHY(PHY_REG_EDCR);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PowerControl/EthernetPowerControl.h Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,299 @@ +/* mbed PowerControl Library + * Copyright (c) 2010 Michael Wei + */ + +#ifndef MBED_POWERCONTROL_ETH_H +#define MBED_POWERCONTROL_ETH_H + +#include "mbed.h" +#include "PowerControl.h" + +#define PHY_REG_BMCR_POWERDOWN 0xB +#define PHY_REG_EDCR_ENABLE 0xF + + +void EMAC_Init(); +static unsigned short read_PHY (unsigned int PhyReg); +static void write_PHY (unsigned int PhyReg, unsigned short Value); + +void PHY_PowerDown(void); +void PHY_PowerUp(void); +void PHY_EnergyDetect_Enable(void); +void PHY_EnergyDetect_Disable(void); + +//From NXP Sample Code .... Probably from KEIL sample code +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ + +/* EMAC variables located in 16K Ethernet SRAM */ +#define RX_DESC_BASE 0x20080000 +#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*8) +#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*8) +#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*8) +#define RX_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*4) +#define TX_BUF_BASE (RX_BUF_BASE + NUM_RX_FRAG*ETH_FRAG_SIZE) + +/* RX and TX descriptor and status definitions. */ +#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) +#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) +#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) +#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) +#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) +#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) +#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) +#define RX_BUF(i) (RX_BUF_BASE + ETH_FRAG_SIZE*i) +#define TX_BUF(i) (TX_BUF_BASE + ETH_FRAG_SIZE*i) + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000001C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier */ +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PowerControl/PowerControl.h Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,191 @@
+/* mbed PowerControl Library
+ * Copyright (c) 2010 Michael Wei
+ */
+
+#ifndef MBED_POWERCONTROL_H
+#define MBED_POWERCONTROL_H
+
+//shouldn't have to include, but fixes weird problems with defines
+//#include "LPC1768/LPC17xx.h"
+//System Control Register
+// bit 0: Reserved
+// bit 1: Sleep on Exit
+#define LPC1768_SCR_SLEEPONEXIT 0x2
+// bit 2: Deep Sleep
+#define LPC1768_SCR_SLEEPDEEP 0x4
+// bit 3: Resereved
+// bit 4: Send on Pending
+#define LPC1768_SCR_SEVONPEND 0x10
+// bit 5-31: Reserved
+
+//Power Control Register
+// bit 0: Power mode control bit 0 (power-down mode)
+#define LPC1768_PCON_PM0 0x1
+// bit 1: Power mode control bit 1 (deep power-down mode)
+#define LPC1768_PCON_PM1 0x2
+// bit 2: Brown-out reduced power mode
+#define LPC1768_PCON_BODRPM 0x4
+// bit 3: Brown-out global disable
+#define LPC1768_PCON_BOGD 0x8
+// bit 4: Brown-out reset disable
+#define LPC1768_PCON_BORD 0x10
+// bit 5-7 : Reserved
+// bit 8: Sleep Mode Entry Flag
+#define LPC1768_PCON_SMFLAG 0x100
+// bit 9: Deep Sleep Entry Flag
+#define LPC1768_PCON_DSFLAG 0x200
+// bit 10: Power Down Entry Flag
+#define LPC1768_PCON_PDFLAG 0x400
+// bit 11: Deep Power Down Entry Flag
+#define LPC1768_PCON_DPDFLAG 0x800
+// bit 12-31: Reserved
+
+//"Sleep Mode" (WFI).
+inline void Sleep(void)
+{
+ __WFI();
+}
+
+//"Deep Sleep" Mode
+inline void DeepSleep(void)
+{
+ SCB->SCR |= LPC1768_SCR_SLEEPDEEP;
+ __WFI();
+}
+
+//"Power-Down" Mode
+inline void PowerDown(void)
+{
+ SCB->SCR |= LPC1768_SCR_SLEEPDEEP;
+ LPC_SC->PCON &= ~LPC1768_PCON_PM1;
+ LPC_SC->PCON |= LPC1768_PCON_PM0;
+ __WFI();
+ //reset back to normal
+ LPC_SC->PCON &= ~(LPC1768_PCON_PM1 | LPC1768_PCON_PM0);
+}
+
+//"Deep Power-Down" Mode
+inline void DeepPowerDown(void)
+{
+ SCB->SCR |= LPC1768_SCR_SLEEPDEEP;
+ LPC_SC->PCON |= LPC1768_PCON_PM1 | LPC1768_PCON_PM0;
+ __WFI();
+ //reset back to normal
+ LPC_SC->PCON &= ~(LPC1768_PCON_PM1 | LPC1768_PCON_PM0);
+}
+
+//shut down BOD during power-down/deep sleep
+inline void BrownOut_ReducedPowerMode_Enable(void)
+{
+ LPC_SC->PCON |= LPC1768_PCON_BODRPM;
+}
+
+//turn on BOD during power-down/deep sleep
+inline void BrownOut_ReducedPowerMode_Disable(void)
+{
+ LPC_SC->PCON &= ~LPC1768_PCON_BODRPM;
+}
+
+//turn off brown out circutry
+inline void BrownOut_Global_Disable(void)
+{
+ LPC_SC->PCON |= LPC1768_PCON_BOGD;
+}
+
+//turn on brown out circutry
+inline void BrownOut_Global_Enable(void)
+{
+ LPC_SC->PCON &= !LPC1768_PCON_BOGD;
+}
+
+//turn off brown out reset circutry
+inline void BrownOut_Reset_Disable(void)
+{
+ LPC_SC->PCON |= LPC1768_PCON_BORD;
+}
+
+//turn on brown outreset circutry
+inline void BrownOut_Reset_Enable(void)
+{
+ LPC_SC->PCON &= ~LPC1768_PCON_BORD;
+}
+//Peripheral Control Register
+// bit 0: Reserved
+// bit 1: PCTIM0: Timer/Counter 0 power/clock enable
+#define LPC1768_PCONP_PCTIM0 0x2
+// bit 2: PCTIM1: Timer/Counter 1 power/clock enable
+#define LPC1768_PCONP_PCTIM1 0x4
+// bit 3: PCUART0: UART 0 power/clock enable
+#define LPC1768_PCONP_PCUART0 0x8
+// bit 4: PCUART1: UART 1 power/clock enable
+#define LPC1768_PCONP_PCUART1 0x10
+// bit 5: Reserved
+// bit 6: PCPWM1: PWM 1 power/clock enable
+#define LPC1768_PCONP_PCPWM1 0x40
+// bit 7: PCI2C0: I2C interface 0 power/clock enable
+#define LPC1768_PCONP_PCI2C0 0x80
+// bit 8: PCSPI: SPI interface power/clock enable
+#define LPC1768_PCONP_PCSPI 0x100
+// bit 9: PCRTC: RTC power/clock enable
+#define LPC1768_PCONP_PCRTC 0x200
+// bit 10: PCSSP1: SSP interface 1 power/clock enable
+#define LPC1768_PCONP_PCSSP1 0x400
+// bit 11: Reserved
+// bit 12: PCADC: A/D converter power/clock enable
+#define LPC1768_PCONP_PCADC 0x1000
+// bit 13: PCCAN1: CAN controller 1 power/clock enable
+#define LPC1768_PCONP_PCCAN1 0x2000
+// bit 14: PCCAN2: CAN controller 2 power/clock enable
+#define LPC1768_PCONP_PCCAN2 0x4000
+// bit 15: PCGPIO: GPIOs power/clock enable
+#define LPC1768_PCONP_PCGPIO 0x8000
+// bit 16: PCRIT: Repetitive interrupt timer power/clock enable
+#define LPC1768_PCONP_PCRIT 0x10000
+// bit 17: PCMCPWM: Motor control PWM power/clock enable
+#define LPC1768_PCONP_PCMCPWM 0x20000
+// bit 18: PCQEI: Quadrature encoder interface power/clock enable
+#define LPC1768_PCONP_PCQEI 0x40000
+// bit 19: PCI2C1: I2C interface 1 power/clock enable
+#define LPC1768_PCONP_PCI2C1 0x80000
+// bit 20: Reserved
+// bit 21: PCSSP0: SSP interface 0 power/clock enable
+#define LPC1768_PCONP_PCSSP0 0x200000
+// bit 22: PCTIM2: Timer 2 power/clock enable
+#define LPC1768_PCONP_PCTIM2 0x400000
+// bit 23: PCTIM3: Timer 3 power/clock enable
+#define LPC1768_PCONP_PCQTIM3 0x800000
+// bit 24: PCUART2: UART 2 power/clock enable
+#define LPC1768_PCONP_PCUART2 0x1000000
+// bit 25: PCUART3: UART 3 power/clock enable
+#define LPC1768_PCONP_PCUART3 0x2000000
+// bit 26: PCI2C2: I2C interface 2 power/clock enable
+#define LPC1768_PCONP_PCI2C2 0x4000000
+// bit 27: PCI2S: I2S interface power/clock enable
+#define LPC1768_PCONP_PCI2S 0x8000000
+// bit 28: Reserved
+// bit 29: PCGPDMA: GP DMA function power/clock enable
+#define LPC1768_PCONP_PCGPDMA 0x20000000
+// bit 30: PCENET: Ethernet block power/clock enable
+#define LPC1768_PCONP_PCENET 0x40000000
+// bit 31: PCUSB: USB interface power/clock enable
+#define LPC1768_PCONP_PCUSB 0x80000000
+
+//Powers Up specified Peripheral(s)
+inline unsigned int Peripheral_PowerUp(unsigned int bitMask)
+{
+ return LPC_SC->PCONP |= bitMask;
+}
+
+//Powers Down specified Peripheral(s)
+inline unsigned int Peripheral_PowerDown(unsigned int bitMask)
+{
+ return LPC_SC->PCONP &= ~bitMask;
+}
+
+//returns if the peripheral is on or off
+inline bool Peripheral_GetStatus(unsigned int peripheral)
+{
+ return (LPC_SC->PCONP & peripheral) ? true : false;
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/kimberlylie99/code/SDFileSystem/#d53f522f398a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,528 @@
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include "ultrasonic.h"
+#include "rtos.h"
+#include "PinDetect.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
+#include "PowerControl/PowerControl.h"
+#include "PowerControl/EthernetPowerControl.h"
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <time.h>
+
+// --------------------------------------- Pin Declarations ---------------------------------------
+// Pins used for WiFi
+Serial pc(USBTX, USBRX);
+Serial esp(p9, p10); // tx, rx
+DigitalOut reset(p26);
+Timer t;
+
+// Pins used for uLCD and Sonar
+uLCD_4DGL uLCD(p28, p27, p29); // serial tx, serial rx, reset pin;
+DigitalOut led1(LED1);
+PinDetect pb(p25);
+Mutex howMany;
+
+// Pins used for SD card and speaker
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+AnalogOut DACout(p18);
+wave_player waver(&DACout);
+
+// Pins used for Bluetooth
+RawSerial blue(p13,p14);
+
+// --------------------------------------- Variable Declarations ---------------------------------------
+// Variables used for WiFi
+int lcount,lended,ltimeout;
+char buf[2024];
+char snd[1024];
+char ssid[32] = "CustomFi"; // enter WiFi router ssid inside the quotes
+char pwd [32] = "#KeepBallin19"; // enter WiFi router password inside the quotes
+
+// Variables used for uLCD and Sonar
+int year, month, day, hr, mn, sec;
+int howManyTodayold = 0;
+int howManyToday = 0;
+int dailyLimit;
+double increment = 0; // DEFAULT: USE DATABASE TO UPDATE THE AMOUNT
+std::string foodName = ""; // so save the food name
+std::string macroName = ""; // to save user's desired macro
+std::string daily = ""; // to save daily amount
+std:: string stringTime = ""; // to save current time and date
+std:: string todayIs = "";
+
+// --------------------------------------- Function Declarations ---------------------------------------
+// Function declarations for WiFi
+double queryMFP(string, string);
+double MFP_LookupTest(string, string);
+void SendCMD(),getreply(),ESPconfig();
+
+// Function declarations for uLCD and Sonar
+time_t asUnixTime(int, int, int, int, int, int);
+void dist(int);
+void updateHowManyToday(void);
+
+// Function declarations for speaker and sd card
+void play_song();
+void updateTime();
+
+// --------------------------------------- Begin Code ---------------------------------------
+// Functions used for WiFi
+double queryMFP(string food, string macro)
+{
+ wait(1);
+ strcpy(snd,"srv = net.createConnection(net.TCP, 0)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd,"srv:on(\"receive\", function(sck, c) print(c) end)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd,"srv:connect(80,\"spectrosam.org\")\r\n");
+ SendCMD();
+ wait(1);
+ sprintf(snd, "sck:send(\"GET /trial.php?query=%s HTTP/1.1\r\nHost: http://spectrosam.org/\r\nAccept: */*\r\n\r\n\")", food);
+ SendCMD();
+ wait(1);
+ ltimeout=15;
+ getreply();
+ pc.printf(buf);
+
+ string resp(buf);
+ size_t found = resp.find(macro);
+ int start = found + macro.size() + 2; //after finding the macro string, go to the end of it, and add two for the quotes and colon
+ int end = start + 3; // D.D of macro value
+ string input = resp.substr(start,end);
+
+ // convert string to char array
+ int n = input.length();
+ // declaring character array
+ char char_array[n + 1];
+ // copying the contents of the
+ // string to char array
+ strcpy(char_array, input.c_str());
+ return atoll(char_array);
+}
+
+void ESPconfig()
+{
+ wait(5);
+ pc.printf("\f---------- Starting ESP Config ----------\r\n\n");
+ strcpy(snd,".\r\n.\r\n");
+ SendCMD();
+ wait(1);
+ pc.printf("---------- Reset & get Firmware ----------\r\n");
+ strcpy(snd,"node.restart()\r\n");
+ SendCMD();
+ ltimeout=5;
+ getreply();
+ pc.printf(buf);
+ wait(2);
+
+ // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station)
+ pc.printf("\n---------- Setting Mode ----------\r\n");
+ strcpy(snd, "wifi.setmode(wifi.STATION)\r\n");
+ SendCMD();
+ ltimeout=4;
+ getreply();
+ pc.printf(buf);
+ wait(2);
+
+ pc.printf("\n---------- Connecting to AP ----------\r\n");
+ pc.printf("ssid = %s pwd = %s\r\n",ssid,pwd);
+ strcpy(snd, "wifi.sta.config(\"");
+ strcat(snd, ssid);
+ strcat(snd, "\",\"");
+ strcat(snd, pwd);
+ strcat(snd, "\")\r\n");
+ SendCMD();
+ ltimeout=10;
+ getreply();
+ pc.printf(buf);
+
+ wait(5);
+
+}
+
+void SendCMD()
+{
+ esp.printf("%s", snd);
+}
+
+void getreply()
+{
+ memset(buf, '\0', sizeof(buf));
+ t.start();
+ lended=0;
+ lcount=0;
+ while(!lended) {
+ if(esp.readable()) {
+ buf[lcount] = esp.getc();
+ lcount++;
+ }
+ if(t.read() > ltimeout) {
+ lended = 1;
+ t.stop();
+ t.reset();
+ }
+ }
+}
+
+time_t asUnixTime(int year, int mon, int mday, int hour, int min, int sec) {
+ struct tm t;
+ t.tm_year = year - 1900;
+ t.tm_mon = mon - 1; // convert to 0 based month
+ t.tm_mday = mday;
+ t.tm_hour = hour;
+ t.tm_min = min;
+ t.tm_sec = sec;
+ t.tm_isdst = -1; // Is Daylight saving time on? 1 = yes, 0 = no, -1 = unknown
+
+ return mktime(&t); // returns seconds elapsed since January 1, 1970 (begin of the Epoch)
+}
+
+void dist(int distance)
+{
+ //put code here to execute when the distance has changed
+ led1 = !led1;
+ howMany.lock();
+ if (howManyToday != howManyTodayold) {
+ updateTime();
+ if (howManyToday >= dailyLimit) {
+ uLCD.cls();
+ uLCD.text_width(2);
+ uLCD.text_height(2);
+ uLCD.filled_rectangle(0,0,127,127,RED);
+ uLCD.filled_rectangle(15,10,110,90,0x50C878);
+ uLCD.textbackground_color(0x50C878);
+ uLCD.color(BLACK);
+ uLCD.locate(2,1);
+ uLCD.printf("Hello!");
+ uLCD.locate(3,3);
+ uLCD.text_width(1);
+ uLCD.text_height(2);
+ uLCD.printf("%d / %d\n", howManyToday, dailyLimit);
+ uLCD.color(BLACK);
+ uLCD.text_width(1);
+ uLCD.text_height(2);
+ uLCD.textbackground_color(RED);
+ uLCD.locate(6,14);
+ uLCD.printf("%s", macroName);
+
+ // Play warning song
+ play_song();
+
+ } else {
+ uLCD.cls();
+ uLCD.text_width(2);
+ uLCD.text_height(2);
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.filled_rectangle(15,10,110,90,0x50C878);
+ uLCD.textbackground_color(0x50C878);
+ uLCD.color(BLACK);
+ uLCD.locate(2,1);
+ uLCD.printf("Hello!");
+ uLCD.locate(3,3);
+ uLCD.text_width(1);
+ uLCD.text_height(2);
+ uLCD.printf("%d / %d\n", howManyToday, dailyLimit);
+ uLCD.color(BLACK);
+ uLCD.text_width(1);
+ uLCD.text_height(1);
+ uLCD.locate(6,14);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.printf("%s", macroName);
+
+ }
+ howManyTodayold = howManyToday;
+ }
+ howMany.unlock();
+ //pc.printf("Distance %d mm\r\n", distance);
+}
+
+ultrasonic mu(p11, p12, .1, 1, &dist); //Set the trigger pin to D12 and the echo pin to D13
+ //have updates every .1 seconds and a timeout after 1
+ //second, and call dist when the distance changes
+
+void updateHowManyToday(void) {
+ if (mu.getCurrentDistance() < 50) {
+ howMany.lock();
+ howManyTodayold = howManyToday;
+ howManyToday = howManyToday + (int)increment;
+ howMany.unlock();
+ }
+}
+
+// Functions used for speaker and sd card
+void play_song() {
+ std::string song = "/sd/NoNoNo3.wav";
+ FILE *wave_file;
+ wave_file=fopen(song.c_str(),"r");
+ waver.play(wave_file);
+ fclose(wave_file);
+}
+
+void updateTime(){
+ time_t curTime = time(NULL);
+ FILE *fp = fopen("/sd/Logging.csv", "a");
+ std:: string test = asctime(localtime(&curTime));
+ if (todayIs.compare(test.substr(0,10)) != 0){
+ howManyToday = 0;
+ todayIs = test.substr(0,10);
+ fprintf(fp, "\n%s\n\n", todayIs.c_str());
+ }
+ fprintf(fp, "%s, %d g, %s\n", foodName.c_str(), (int)increment, macroName.c_str());
+ fclose(fp);
+}
+
+int main() {
+ // Start of uLCD code
+ bool startUp = 1, name = 1, limit = 1, settingTime = 1;
+ uLCD.cls();
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.line(0, 9, 127, 9, GREEN);
+ uLCD.filled_rectangle(0,0,127,9,GREEN);
+ uLCD.line(0, 118, 127, 118, GREEN);
+ uLCD.filled_rectangle(0,118,127,127,GREEN);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.color(DGREY);
+ uLCD.text_height(1.80);
+
+ uLCD.locate(4,2);
+ uLCD.printf("WELCOME!");
+ uLCD.color(BLACK);
+ uLCD.locate(1,4);
+ uLCD.printf("Please enter the name");
+ uLCD.printf(" of the food.");
+ uLCD.color(BLACK);
+ uLCD.locate(1,7);
+
+ while (name) {
+ if (blue.readable()) {
+ char v = blue.getc();
+ if (v == '!'){
+ name = 0;
+ } else if (int(v) == 8) {
+ foodName.erase(foodName.end()-1);
+ } else {
+ foodName.push_back(v);
+ uLCD.printf("%c" , v);
+ }
+ }
+ }
+
+ uLCD.cls();
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.line(0, 9, 127, 9, GREEN);
+ uLCD.filled_rectangle(0,0,127,9,GREEN);
+ uLCD.line(0, 118, 127, 118, GREEN);
+ uLCD.filled_rectangle(0,118,127,127,GREEN);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.color(BLACK);
+ uLCD.text_height(1);
+
+ uLCD.locate(1,1);
+ uLCD.printf("What macro are you monitoring? : \n\n1. Carbs\n2. Protein\n3. Fat \n4. Calories \n");
+ uLCD.color(BLACK);
+ while(startUp) {
+ if (blue.readable() ){
+ char v = blue.getc();
+ if (v == '1') {
+ startUp = 0;
+ macroName = "Carbs";
+ } else if (v == '2') {
+ startUp = 0;
+ macroName = "Protein";
+ } else if (v == '3') {
+ startUp = 0;
+ macroName = "Fat";
+ } else if (v == '4') {
+ startUp = 0;
+ macroName = "Calories";
+
+ }
+ }
+ }
+
+ uLCD.cls();
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.line(0, 9, 127, 9, GREEN);
+ uLCD.filled_rectangle(0,0,127,9,GREEN);
+ uLCD.line(0, 118, 127, 118, GREEN);
+ uLCD.filled_rectangle(0,118,127,127,GREEN);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.color(BLACK);
+ uLCD.locate(1,2);
+ uLCD.text_height(1);
+
+ uLCD.printf("What will be your daily limit?\n ");
+ uLCD.color(BLACK);
+
+ while (limit) {
+ if (blue.readable()){
+ char v = blue.getc();
+ if (v == '!') {
+ limit = 0;
+ } else {
+ daily.push_back(v);
+ uLCD.printf("%c" , v);
+ }
+ }
+
+ }
+
+ std::istringstream iss (daily);
+ iss >> dailyLimit;
+
+ uLCD.cls();
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.line(0, 9, 127, 9, GREEN);
+ uLCD.filled_rectangle(0,0,127,9,GREEN);
+ uLCD.line(0, 118, 127, 118, GREEN);
+ uLCD.filled_rectangle(0,118,127,127,GREEN);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.color(BLACK);
+ uLCD.text_height(1);
+ uLCD.locate(1,1);
+ uLCD.printf("Please enter date and military time\nMM/DD/YYYY HH:MM:SS)\n");
+ uLCD.color(BLACK);
+
+ while (settingTime) {
+ if (blue.readable()){
+ char v = blue.getc();
+ if (v == '!') {
+ settingTime = 0;
+ } else {
+ stringTime.push_back(v);
+ uLCD.printf("%c" , v);
+ }
+ }
+ }
+
+ // Start of WiFi code
+ reset=0;
+ pc.baud(9600);
+ pc.printf("\f\n\r-------------ESP8266 Hardware Reset-------------\n\r");
+ wait(0.5);
+ reset=1;
+ ltimeout=2;
+ getreply();
+ esp.baud(9600); // ESP baud rate
+ ESPconfig();
+ increment = queryMFP(foodName, macro);
+
+ // After calling database
+ // TIME
+ // converts epoch time to day, month, year
+ std::istringstream mon (stringTime.substr(0,2));
+ mon >> month;
+ std::istringstream d (stringTime.substr(3,2));
+ d >> day;
+ std::istringstream y (stringTime.substr(6,4));
+ y >> year;
+ std::istringstream h (stringTime.substr(11,2));
+ h >> hr;
+ std::istringstream m (stringTime.substr(14,2));
+ m >> mn;
+ std::istringstream sc (stringTime.substr(17,2));
+ sc >> sec;
+
+ time_t result = asUnixTime(year, month, day, hr, mn, sec);
+
+ pc.printf("%s\n",asctime(localtime(&result)));
+
+ set_time(result);
+
+ todayIs = asctime(localtime(&result));
+ todayIs = todayIs.substr(0,3);
+
+ uLCD.cls();
+ uLCD.filled_rectangle(0,0,127,127,0x86c5da);
+ uLCD.filled_rectangle(15,10,110,90,0x50C878);
+ uLCD.textbackground_color(0x50C878);
+ uLCD.color(BLACK);
+ uLCD.text_width(2);
+ uLCD.text_height(2);
+ uLCD.locate(2,1);
+ uLCD.printf("Hello!");
+ uLCD.locate(3,3);
+ uLCD.text_width(1);
+ uLCD.text_height(2);
+ uLCD.printf("%d / %d", howManyToday, dailyLimit);
+ uLCD.color(BLACK);
+ uLCD.textbackground_color(0x86c5da);
+ uLCD.text_width(1);
+ uLCD.text_height(1);
+ uLCD.locate(6,14);
+ uLCD.printf("%s", macroName);
+
+ pc.baud(9600);
+ mu.startUpdates();//start measuring the distance
+ pb.attach_deasserted(&updateHowManyToday);
+ pb.mode(PullUp);
+ pb.setSampleFrequency();
+
+ //checkTime.attach(&updateTime, 10);
+
+ // PWR MNGT
+ PHY_PowerDown();
+ //Peripheral_PowerDown(0xFEF6FFCF);
+ Peripheral_PowerDown(LPC1768_PCONP_PCTIM0); // Timer/Counter 0
+ Peripheral_PowerDown(LPC1768_PCONP_PCTIM1); // Timer/Counter 1
+ Peripheral_PowerDown(LPC1768_PCONP_PCUART0); //UART 0
+ Peripheral_PowerDown(LPC1768_PCONP_PCUART1); //UART 1
+ Peripheral_PowerDown(LPC1768_PCONP_PCPWM1); // PWM
+ Peripheral_PowerDown(LPC1768_PCONP_PCI2C0); //bit 7: I2c interface
+ Peripheral_PowerDown(LPC1768_PCONP_PCSPI); //SPI
+ Peripheral_PowerDown(LPC1768_PCONP_PCRTC); //RTC
+ Peripheral_PowerDown(LPC1768_PCONP_PCSSP1); //SSP
+
+ // bit 11: Reserved
+ //Peripheral_PowerDown(LPC1768_PCONP_PCADC); // bit12: A/D converter power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCCAN1); // bit 13: CAN controller 1 power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCCAN2); // bit 14: CAN controller 2 power/clock enable
+
+ // bit 15: PCGPIO: GPIOs power/clock enable
+ //Peripheral_PowerDown(LPC1768_PCONP_PCGPIO);
+
+ Peripheral_PowerDown(LPC1768_PCONP_PCRIT); //bit 16: Repetitive interrupt timer power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCMCPWM); // bit 17: Motor control PWM power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCQEI); // bit 18: Quadrature encoder interface power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCI2C1); // bit 19: I2C interface 1 power/clock enable
+
+ // bit 20: Reserved
+ Peripheral_PowerDown(LPC1768_PCONP_PCSSP0); // bit 21: PCSSP0: SSP interface 0 power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCTIM2); // bit 22: PCTIM2: Timer 2 power/clock enable
+
+ // bit 23: PCTIM3: Timer 3 power/clock enable
+ //Peripheral_PowerDown(LPC1768_PCONP_PCQTIM3);
+
+ // bit 24: PCUART2: UART 2 power/clock enable
+ //Peripheral_PowerDown(LPC1768_PCONP_PCUART2);
+
+ Peripheral_PowerDown(LPC1768_PCONP_PCUART3); // bit 25: UART 3 power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCI2C2); // bit 26: I2C interface 2 power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCI2S); // bit 27: PCI2S: I2S interface power/clock enable
+
+ // bit 28: Reserved
+ Peripheral_PowerDown(LPC1768_PCONP_PCGPDMA); // bit 29:GP DMA function power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCENET); // bit 30:Ethernet block power/clock enable
+ Peripheral_PowerDown(LPC1768_PCONP_PCUSB); // bit 31: PCUSB: USB interface power/clock enable
+
+ // only BIT 23, 24, 15 need to be on, but htis ths isnt working
+ //Peripheral_PowerDown(0xFFFEFE7F);
+ //Peripheral_PowerDown(0x7BEEF677);
+
+ // Sonar code
+ while(1)
+ {
+ //pc.printf("Distance %d mm\r\n", mu.getCurrentDistance());
+ Sleep();
+ mu.checkDistance(); //call checkDistance() as much as possible, as this is where
+ //the class checks if dist needs to be called.
+ wait(0.002);
+ }
+}
+
+// --------------------------------------- End Code ---------------------------------------
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed-rtos/#5713cbbdb706
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Apr 30 00:27:23 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uLCD_4DGL.h Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,346 @@
+//
+// uLCD_4DGL is a class to drive 4D Systems TFT touch screens
+//
+// Fork of 4DGL library for 4D Systems LCD displays
+// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
+// Modifed for Goldelox processor <2013> Jim Hamblen
+//
+// uLCD_4DGL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// uLCD_4DGL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
+
+// @author Stephane Rochon
+
+#include "mbed.h"
+
+// Debug Verbose off - SGE commands echoed to USB serial for debugmode=1
+#ifndef DEBUGMODE
+#define DEBUGMODE 0
+#endif
+
+// Common WAIT value in milliseconds between commands
+#define TEMPO 0
+
+// 4DGL SGE Function values for Goldelox Processor
+#define CLS '\xD7'
+#define BAUDRATE '\x0B' //null prefix
+#define VERSION '\x08' //null prefix
+#define BCKGDCOLOR '\x6E'
+#define TXTBCKGDCOLOR '\x7E'
+#define DISPCONTROL '\x68'
+#define SETVOLUME '\x76'
+#define CIRCLE '\xCD'
+#define FCIRCLE '\xCC'
+#define TRIANGLE '\xC9'
+#define LINE '\xD2'
+#define FRECTANGLE '\xCE'
+#define RECTANGLE '\xCF'
+#define ELLIPSE '\x65' //na
+#define PIXEL '\xCB'
+#define READPIXEL '\xCA'
+#define SCREENCOPY '\x63' //na?
+#define PENSIZE '\xD8'
+#define SETFONT '\x7D'
+#define TEXTMODE '\x77'
+#define TEXTBOLD '\x76'
+#define TEXTITALIC '\x75'
+#define TEXTINVERSE '\x74'
+#define TEXTUNDERLINE '\x73'
+#define TEXTWIDTH '\x7C'
+#define TEXTHEIGHT '\x7B'
+#define TEXTCHAR '\xFE'
+#define TEXTSTRING '\x06' //null prefix
+#define MOVECURSOR '\xE4'
+#define BLITCOM '\x0A'
+#define PUTCHAR '\xFE'
+#define DISPPOWER '\x66'
+//media commands for uSD card
+#define MINIT '\xB1'
+#define SBADDRESS '\xB9'
+#define SSADDRESS '\xB8'
+#define READBYTE '\xB7'
+#define READWORD '\xB6'
+#define WRITEBYTE '\xB5'
+#define WRITEWORD '\xB4'
+#define FLUSHMEDIA '\xB2'
+#define DISPLAYIMAGE '\xB3'
+#define DISPLAYVIDEO '\xBB'
+#define DISPLAYFRAME '\xBA'
+
+
+
+// Screen answers
+#define ACK '\x06'
+#define NAK '\x15'
+
+
+
+// Screen states
+#define OFF '\x00'
+#define ON '\x01'
+
+// Graphics modes
+#define SOLID '\x00'
+#define WIREFRAME '\x01'
+
+// Text modes
+#define TRANSPARENT '\x00'
+#define OPAQUE '\x01'
+
+// Fonts Sizes
+#define FONT_7X8 '\x00' //only builtin font
+#define FONT_5X7 '\x04'
+#define FONT_8X8 '\x01'
+#define FONT_8X12 '\x02'
+#define FONT_12X16 '\x03'
+#define MEDIAFONT '\x07'
+
+
+// Data speed
+#define BAUD_110 27271
+#define BAUD_300 9999
+#define BAUD_600 4999
+#define BAUD_1200 2499
+#define BAUD_2400 1249
+#define BAUD_4800 624
+#define BAUD_9600 312
+#define BAUD_14400 207
+#define BAUD_19200 155
+#define BAUD_31250 95
+#define BAUD_38400 77
+#define BAUD_56000 53
+#define BAUD_57600 51
+#define BAUD_115200 25
+#define BAUD_128000 22
+#define BAUD_256000 11
+#define BAUD_300000 10
+#define BAUD_375000 8
+#define BAUD_500000 6
+#define BAUD_600000 4
+#define BAUD_750000 3
+#define BAUD_1000000 2
+#define BAUD_1500000 1
+#define BAUD_3000000 0
+
+// Defined Colors
+#define WHITE 0xFFFFFF
+#define BLACK 0x000000
+#define RED 0xFF0000
+#define GREEN 0x00FF00
+#define BLUE 0x0000FF
+#define LGREY 0xBFBFBF
+#define DGREY 0x5F5F5F
+
+// Mode data
+#define BACKLIGHT '\x00'
+#define DISPLAY '\x01'
+#define CONTRAST '\x02'
+#define POWER '\x03'
+#define ORIENTATION '\x04'
+#define TOUCH_CTRL '\x05'
+#define IMAGE_FORMAT '\x06'
+#define PROTECT_FAT '\x08'
+
+// change this to your specific screen (newer versions) if needed
+// Startup orientation is PORTRAIT so SIZE_X must be lesser than SIZE_Y
+//uLCD144-G2 is a 128 by 128 pixel display
+#define SIZE_X 128
+#define SIZE_Y 128
+
+#define IS_LANDSCAPE 0
+#define IS_PORTRAIT 1
+
+// Screen orientation
+#define LANDSCAPE '\x00'
+#define LANDSCAPE_R '\x01'
+#define PORTRAIT '\x02'
+#define PORTRAIT_R '\x03'
+
+// Parameters
+#define ENABLE '\x00'
+#define DISABLE '\x01'
+#define RESET '\x02'
+
+#define NEW '\x00'
+#define OLD '\x01'
+
+#define DOWN '\x00'
+#define UP '\x01'
+
+#define PROTECT '\x00'
+#define UNPROTECT '\x02'
+
+//**************************************************************************
+// \class uLCD_4DGL uLCD_4DGL.h
+// \brief This is the main class. It shoud be used like this : uLCD_4GDL myLCD(p9,p10,p11);
+/**
+Example:
+* @code
+* // Display a white circle on the screen
+* #include "mbed.h"
+* #include " uLCD_4DGL.h"
+*
+* uLCD_4GDL myLCD(p9,p10,p11);
+*
+* int main() {
+* myLCD.circle(120, 160, 80, WHITE);
+* }
+* @endcode
+*/
+
+class uLCD_4DGL : public Stream
+{
+
+public :
+
+ uLCD_4DGL(PinName tx, PinName rx, PinName rst);
+
+// General Commands *******************************************************************************
+
+ /** Clear the entire screen using the current background colour */
+ void cls();
+
+ /** Reset screen */
+ void reset();
+
+
+ /** Set serial Baud rate (both sides : screen and mbed)
+ * @param Speed Correct BAUD value (see uLCD_4DGL.h)
+ */
+ void baudrate(int speed);
+
+ /** Set background colour to the specified value
+ * @param color in HEX RGB like 0xFF00FF
+ */
+ void background_color(int color);
+
+ /** Set screen display mode to specific values
+ * @param mode See 4DGL documentation
+ * @param value See 4DGL documentation
+ */
+ void textbackground_color(int color);
+
+ /** Set screen display mode to specific values
+ * @param mode See 4DGL documentation
+ * @param value See 4DGL documentation
+ */
+ void display_control(char mode);
+ void display_power(char mode);
+ /** Set internal speaker to specified value
+ * @param value Correct range is 8 - 127
+ */
+ void set_volume(char value);
+
+// Graphics Commands *******************************************************************************
+
+ /** Draw a circle centered at x,y with a radius and a colour. It uses Pen Size stored value to draw a solid or wireframe circle
+ * @param x Horizontal position of the circle centre
+ * @param y Vertical position of the circle centre
+ * @param radius Radius of the circle
+ * @param color Circle color in HEX RGB like 0xFF00FF
+ */
+ void circle(int x , int y , int radius, int color);
+ void filled_circle(int x , int y , int radius, int color);
+ void triangle(int, int, int, int, int, int, int);
+ void line(int, int, int, int, int);
+ void rectangle(int, int, int, int, int);
+ void filled_rectangle(int, int, int, int, int);
+ void pixel(int, int, int);
+ int read_pixel(int, int);
+ void pen_size(char);
+ void BLIT(int x, int y, int w, int h, int *colors);
+
+// Text Commands
+ void set_font(char);
+ void set_font_size(char width, char height);
+ void text_mode(char);
+ void text_bold(char);
+ void text_italic(char);
+ void text_inverse(char);
+ void text_underline(char);
+ void text_width(char);
+ void text_height(char);
+ void text_char(char, char, char, int);
+ void text_string(char *, char, char, char, int);
+ void locate(char, char);
+ void color(int);
+ void putc(char);
+ void puts(char *);
+
+//Media Commands
+ int media_init();
+ void set_byte_address(int, int);
+ void set_sector_address(int, int);
+ char read_byte();
+ int read_word();
+ void write_byte(int);
+ void write_word(int);
+ void flush_media();
+ void display_image(int, int);
+ void display_video(int, int);
+ void display_frame(int, int, int);
+
+// Screen Data
+ int type;
+ int revision;
+ int firmware;
+ int reserved1;
+ int reserved2;
+
+// Text data
+ char current_col;
+ char current_row;
+ int current_color;
+ char current_font;
+ char current_orientation;
+ char max_col;
+ char max_row;
+ int current_w, current_h;
+ int current_fx, current_fy;
+ int current_wf, current_hf;
+
+
+protected :
+
+ Serial _cmd;
+ DigitalOut _rst;
+ //used by printf
+ virtual int _putc(int c) {
+ putc(c);
+ return 0;
+ };
+ virtual int _getc() {
+ return -1;
+ }
+
+ void freeBUFFER (void);
+ void writeBYTE (char);
+ void writeBYTEfast (char);
+ int writeCOMMAND(char *, int);
+ int writeCOMMANDnull(char *, int);
+ int readVERSION (char *, int);
+ int getSTATUS (char *, int);
+ int version (void);
+#if DEBUGMODE
+ Serial pc;
+#endif // DEBUGMODE
+};
+
+typedef unsigned char BYTE;
+
+
+
+
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uLCD_4DGL_Graphics.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,310 @@
+//
+// uLCD_4DGL is a class to drive 4D Systems LCD screens
+//
+// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
+// Modifed for Goldelox processor <2013> Jim Hamblen
+//
+// uLCD_4DGL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// uLCD_4DGL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+
+#define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0])
+
+//****************************************************************************************************
+void uLCD_4DGL :: circle(int x, int y , int radius, int color) // draw a circle in (x,y)
+{
+ char command[9]= "";
+
+ command[0] = CIRCLE;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+
+ command[5] = (radius >> 8) & 0xFF;
+ command[6] = radius & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[7] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[8] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 9);
+}
+//****************************************************************************************************
+void uLCD_4DGL :: filled_circle(int x, int y , int radius, int color) // draw a circle in (x,y)
+{
+ char command[9]= "";
+
+ command[0] = FCIRCLE;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+
+ command[5] = (radius >> 8) & 0xFF;
+ command[6] = radius & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[7] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[8] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 9);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: triangle(int x1, int y1 , int x2, int y2, int x3, int y3, int color) // draw a traingle
+{
+ char command[15]= "";
+
+ command[0] = TRIANGLE;
+
+ command[1] = (x1 >> 8) & 0xFF;
+ command[2] = x1 & 0xFF;
+
+ command[3] = (y1 >> 8) & 0xFF;
+ command[4] = y1 & 0xFF;
+
+ command[5] = (x2 >> 8) & 0xFF;
+ command[6] = x2 & 0xFF;
+
+ command[7] = (y2 >> 8) & 0xFF;
+ command[8] = y2 & 0xFF;
+
+ command[9] = (x3 >> 8) & 0xFF;
+ command[10] = x3 & 0xFF;
+
+ command[11] = (y3 >> 8) & 0xFF;
+ command[12] = y3 & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[13] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[14] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 15);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: line(int x1, int y1 , int x2, int y2, int color) // draw a line
+{
+ char command[11]= "";
+
+ command[0] = LINE;
+
+ command[1] = (x1 >> 8) & 0xFF;
+ command[2] = x1 & 0xFF;
+
+ command[3] = (y1 >> 8) & 0xFF;
+ command[4] = y1 & 0xFF;
+
+ command[5] = (x2 >> 8) & 0xFF;
+ command[6] = x2 & 0xFF;
+
+ command[7] = (y2 >> 8) & 0xFF;
+ command[8] = y2 & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[9] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[10] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 11);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: rectangle(int x1, int y1 , int x2, int y2, int color) // draw a rectangle
+{
+ char command[11]= "";
+
+ command[0] = RECTANGLE;
+
+ command[1] = (x1 >> 8) & 0xFF;
+ command[2] = x1 & 0xFF;
+
+ command[3] = (y1 >> 8) & 0xFF;
+ command[4] = y1 & 0xFF;
+
+ command[5] = (x2 >> 8) & 0xFF;
+ command[6] = x2 & 0xFF;
+
+ command[7] = (y2 >> 8) & 0xFF;
+ command[8] = y2 & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[9] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[10] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 11);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: filled_rectangle(int x1, int y1 , int x2, int y2, int color) // draw a rectangle
+{
+ char command[11]= "";
+
+ command[0] = FRECTANGLE;
+
+ command[1] = (x1 >> 8) & 0xFF;
+ command[2] = x1 & 0xFF;
+
+ command[3] = (y1 >> 8) & 0xFF;
+ command[4] = y1 & 0xFF;
+
+ command[5] = (x2 >> 8) & 0xFF;
+ command[6] = x2 & 0xFF;
+
+ command[7] = (y2 >> 8) & 0xFF;
+ command[8] = y2 & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[9] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[10] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 11);
+}
+
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: pixel(int x, int y, int color) // draw a pixel
+{
+ char command[7]= "";
+
+ command[0] = PIXEL;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[5] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[6] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 7);
+}
+//****************************************************************************************************
+void uLCD_4DGL :: BLIT(int x, int y, int w, int h, int *colors) // draw a block of pixels
+{
+ int red5, green6, blue5;
+ writeBYTEfast('\x00');
+ writeBYTEfast(BLITCOM);
+ writeBYTEfast((x >> 8) & 0xFF);
+ writeBYTEfast(x & 0xFF);
+ writeBYTEfast((y >> 8) & 0xFF);
+ writeBYTEfast(y & 0xFF);
+ writeBYTEfast((w >> 8) & 0xFF);
+ writeBYTE(w & 0xFF);
+ writeBYTE((h >> 8) & 0xFF);
+ writeBYTE(h & 0xFF);
+ wait_ms(1);
+ for (int i=0; i<w*h; i++) {
+ red5 = (colors[i] >> (16 + 3)) & 0x1F; // get red on 5 bits
+ green6 = (colors[i] >> (8 + 2)) & 0x3F; // get green on 6 bits
+ blue5 = (colors[i] >> (0 + 3)) & 0x1F; // get blue on 5 bits
+ writeBYTEfast(((red5 << 3) + (green6 >> 3)) & 0xFF); // first part of 16 bits color
+ writeBYTEfast(((green6 << 5) + (blue5 >> 0)) & 0xFF); // second part of 16 bits color
+ }
+ int resp=0;
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) resp = _cmd.getc(); // read response if any
+ switch (resp) {
+ case ACK : // if OK return 1
+ resp = 1;
+ break;
+ case NAK : // if NOK return -1
+ resp = -1;
+ break;
+ default :
+ resp = 0; // else return 0
+ break;
+ }
+#if DEBUGMODE
+ pc.printf(" Answer received : %d\n",resp);
+#endif
+
+}
+//******************************************************************************************************
+int uLCD_4DGL :: read_pixel(int x, int y) // read screen info and populate data
+{
+
+ char command[6]= "";
+ command[0] = 0xFF;
+ command[1] = READPIXEL;
+
+ command[2] = (x >> 8) & 0xFF;
+ command[3] = x & 0xFF;
+
+ command[4] = (y >> 8) & 0xFF;
+ command[5] = y & 0xFF;
+
+ int i, temp = 0, color = 0, resp = 0;
+ char response[2] = "";
+
+ freeBUFFER();
+
+ for (i = 0; i < 6; i++) { // send all chars to serial port
+ writeBYTE(command[i]);
+ }
+
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+
+ while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
+ temp = _cmd.getc();
+ response[resp++] = (char)temp;
+ }
+
+ color = ((response[0] << 8) + response[1]);
+
+ return color; // WARNING : this is 16bits color, not 24bits... need to be fixed
+}
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: pen_size(char mode) // set pen to SOLID or WIREFRAME
+{
+ char command[2]= "";
+
+ command[0] = PENSIZE;
+ command[1] = mode;
+ writeCOMMAND(command, 2);
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uLCD_4DGL_Media.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,177 @@
+//
+// uLCD_4DGL is a class to drive 4D Systems LCD screens
+//
+// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
+// Modifed for Goldelox processor <2013> Jim Hamblen
+//
+// uLCD_4DGL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// uLCD_4DGL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+
+
+//Media Commands
+
+//******************************************************************************************************
+int uLCD_4DGL :: media_init()
+{
+ int resp = 0;
+ char command[1] = "";
+ command[0] = MINIT;
+ writeCOMMAND(command, 1);
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) {
+ resp = _cmd.getc(); // read response
+ resp = resp << 8 + _cmd.getc();
+ }
+ return resp;
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: set_byte_address(int hi, int lo)
+{
+ char command[5]= "";
+ command[0] = SBADDRESS;
+
+ command[1] = (hi >> 8) & 0xFF;
+ command[2] = hi & 0xFF;
+
+ command[3] = (lo >> 8) & 0xFF;
+ command[4] = lo & 0xFF;
+ writeCOMMAND(command, 5);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: set_sector_address(int hi, int lo)
+{
+
+ char command[5]= "";
+ command[0] = SSADDRESS;
+
+ command[1] = (hi >> 8) & 0xFF;
+ command[2] = hi & 0xFF;
+
+ command[3] = (lo >> 8) & 0xFF;
+ command[4] = lo & 0xFF;
+ writeCOMMAND(command, 5);
+}
+
+//******************************************************************************************************
+char uLCD_4DGL :: read_byte()
+{
+ char resp = 0;
+ char command[1] = "";
+ command[0] = READBYTE;
+ writeCOMMAND(command, 1);
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) {
+ resp = _cmd.getc(); // read response
+ resp = _cmd.getc();
+ }
+ return resp;
+}
+
+//******************************************************************************************************
+int uLCD_4DGL :: read_word()
+{
+ int resp=0;
+ char command[1] = "";
+ command[0] = READWORD;
+ writeCOMMAND(command, 1);
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) {
+ resp = _cmd.getc(); // read response
+ resp = resp << 8 + _cmd.getc();
+ }
+ return resp;
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: write_byte(int value)
+{
+ char command[3]= "";
+
+ command[0] = WRITEBYTE;
+
+ command[1] = (value >> 8) & 0xFF;
+ command[2] = value & 0xFF;
+ writeCOMMAND(command,3);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: write_word(int value)
+{
+ char command[3]= "";
+
+ command[0] = WRITEWORD;
+
+ command[1] = (value >> 8) & 0xFF;
+ command[2] = value & 0xFF;
+ writeCOMMAND(command,3);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: flush_media()
+{
+ char command[1] = "";
+ command[0] = FLUSHMEDIA;
+ writeCOMMAND(command, 1);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: display_image(int x, int y)
+{
+ char command[6]= "";
+ command[0] = DISPLAYIMAGE;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+ writeCOMMAND(command, 5);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: display_video(int x, int y)
+{
+ char command[5]= "";
+ command[0] = DISPLAYVIDEO;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+ writeCOMMAND(command, 5);
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: display_frame(int x, int y, int w)
+{
+ char command[7]= "";
+
+ command[0] = DISPLAYFRAME;
+
+ command[1] = (x >> 8) & 0xFF;
+ command[2] = x & 0xFF;
+
+ command[3] = (y >> 8) & 0xFF;
+ command[4] = y & 0xFF;
+
+ command[5] = (w >> 8) & 0xFF;
+ command[6] = w & 0xFF;
+ writeCOMMAND(command,7);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uLCD_4DGL_Text.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,343 @@
+//
+// uLCD_4DGL is a class to drive 4D Systems TFT touch screens
+//
+// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
+// Modifed for Goldelox processor <2013> Jim Hamblen
+//
+// uLCD_4DGL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// uLCD_4DGL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+
+//****************************************************************************************************
+void uLCD_4DGL :: set_font_size(char width, char height) // set font size
+{
+ if (current_orientation == IS_PORTRAIT) {
+ current_fx = width;
+ current_fy = height;
+ } else {
+ current_fy = height;
+ current_fx = width;
+ }
+ max_col = current_w / (current_fx*current_wf);
+ max_row = current_h / (current_fy*current_hf);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: set_font(char mode) // set font - system or SD media
+{
+ char command[3]= "";
+
+ command[0] = SETFONT;
+ command[1] = 0;
+ command[2] = mode;
+
+ current_font = mode;
+
+ if (current_orientation == IS_PORTRAIT) {
+ current_w = SIZE_X;
+ current_h = SIZE_Y;
+ } else {
+ current_w = SIZE_Y;
+ current_h = SIZE_X;
+ }
+
+ switch (mode) {
+ case FONT_5X7 :
+
+ current_fx = 6;
+ current_fy = 8;
+ break;
+ case FONT_7X8 :
+ current_fx = 7;
+ current_fy = 8;
+ break;
+ case FONT_8X8 :
+ current_fx = 8;
+ current_fy = 8;
+ break;
+ case FONT_8X12 :
+ current_fx = 8;
+ current_fy = 12;
+ break;
+ case FONT_12X16 :
+ current_fx = 12;
+ current_fy = 16;
+ break;
+ default:
+ current_fx = 8;
+ current_fy = 8;
+ }
+
+ max_col = current_w / (current_fx*current_wf);
+ max_row = current_h / (current_fy*current_hf);
+
+ writeCOMMAND(command, 3);
+}
+
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_mode(char mode) // set text mode
+{
+ char command[3]= "";
+
+ command[0] = TEXTMODE;
+ command[1] = 0;
+ command[2] = mode;
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_bold(char mode) // set text mode
+{
+ char command[3]= "";
+
+ command[0] = TEXTBOLD;
+ command[1] = 0;
+ command[2] = mode;
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_italic(char mode) // set text mode
+{
+ char command[3]= "";
+
+ command[0] = TEXTITALIC;
+ command[1] = 0;
+ command[2] = mode;
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_inverse(char mode) // set text mode
+{
+ char command[3]= "";
+
+ command[0] = TEXTINVERSE;
+ command[1] = 0;
+ command[2] = mode;
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_underline(char mode) // set text mode
+{
+ char command[3]= "";
+
+ command[0] = TEXTUNDERLINE;
+ command[1] = 0;
+ command[2] = mode;
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_width(char width) // set text width
+{
+ char command[3]= "";
+
+ command[0] = TEXTWIDTH;
+ command[1] = 0;
+ command[2] = width;
+ current_wf = width;
+ max_col = current_w / (current_fx*current_wf);
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_height(char height) // set text height
+{
+ char command[3]= "";
+
+ command[0] = TEXTHEIGHT;
+ command[1] = 0;
+ command[2] = height;
+ current_hf = height;
+ max_row = current_h / (current_fy*current_hf);
+ writeCOMMAND(command, 3);
+}
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_char(char c, char col, char row, int color) // draw a text char
+{
+ char command[6]= "";
+ command[0] = 0xE4; //move cursor
+ command[1] = 0;
+ command[2] = row;
+ command[3] = 0;
+ command[4] = col;
+ writeCOMMAND(command, 5);
+
+ command[0] = 0x7F; //set color
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+ writeCOMMAND(command, 3);
+
+ command[0] = TEXTCHAR; //print char
+ command[1] = 0;
+ command[2] = c;
+ writeCOMMAND(command, 3);
+
+}
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: text_string(char *s, char col, char row, char font, int color) // draw a text string
+{
+
+ char command[1000]= "";
+ int size = strlen(s);
+ int i = 0;
+
+ set_font(font);
+
+ command[0] = 0xE4; //move cursor
+ command[1] = 0;
+ command[2] = row;
+ command[3] = 0;
+ command[4] = col;
+ writeCOMMAND(command, 5);
+
+ command[0] = 0x7F; //set color
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+ writeCOMMAND(command, 3);
+
+ command[0] = TEXTSTRING;
+ for (i=0; i<size; i++) command[1+i] = s[i];
+ command[1+size] = 0;
+ writeCOMMANDnull(command, 2 + size);
+}
+
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: locate(char col, char row) // place text curssor at col, row
+{
+ char command[5] = "";
+ current_col = col;
+ current_row = row;
+ command[0] = MOVECURSOR; //move cursor
+ command[1] = 0;
+ command[2] = current_row;
+ command[3] = 0;
+ command[4] = current_col;
+ writeCOMMAND(command, 5);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: color(int color) // set text color
+{
+ char command[5] = "";
+ current_color = color;
+ command[0] = 0x7F; //set color
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: putc(char c) // place char at current cursor position
+//used by virtual printf function _putc
+{
+ char command[6] ="";
+ if(c<0x20) {
+ if(c=='\n') {
+ current_col = 0;
+ current_row++;
+ command[0] = MOVECURSOR; //move cursor to start of next line
+ command[1] = 0;
+ command[2] = current_row;
+ command[3] = 0;
+ command[4] = current_col;
+ writeCOMMAND(command, 5);
+ }
+ if(c=='\r') {
+ current_col = 0;
+ command[0] = MOVECURSOR; //move cursor to start of line
+ command[1] = 0;
+ command[2] = current_row;
+ command[3] = 0;
+ command[4] = current_col;
+ writeCOMMAND(command, 5);
+ }
+ if(c=='\f') {
+ uLCD_4DGL::cls(); //clear screen on form feed
+ }
+ } else {
+ command[0] = PUTCHAR;
+ command[1] = 0x00;
+ command[2] = c;
+ writeCOMMAND(command,3);
+ current_col++;
+ }
+ if (current_col == max_col) {
+ current_col = 0;
+ current_row++;
+ command[0] = MOVECURSOR; //move cursor to next line
+ command[1] = 0;
+ command[2] = current_row;
+ command[3] = 0;
+ command[4] = current_col;
+ writeCOMMAND(command, 5);
+ }
+ if (current_row == max_row) {
+ current_row = 0;
+ command[0] = MOVECURSOR; //move cursor back to start
+ command[1] = 0;
+ command[2] = current_row;
+ command[3] = 0;
+ command[4] = current_col;
+ writeCOMMAND(command, 5);
+ }
+}
+
+
+//****************************************************************************************************
+void uLCD_4DGL :: puts(char *s) // place string at current cursor position
+{
+
+ text_string(s, current_col, current_row, current_font, current_color);
+
+ current_col += strlen(s);
+
+ if (current_col >= max_col) {
+ current_row += current_col / max_col;
+ current_col %= max_col;
+ }
+ if (current_row >= max_row) {
+ current_row %= max_row;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uLCD_4DGL_main.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,469 @@
+//
+// uLCD_4DGL is a class to drive 4D Systems uLCD 144 G2
+//
+// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
+// Modifed for Goldelox processor <2013> Jim Hamblen
+//
+// uLCD_4DGL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// uLCD_4DGL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with uLCD_4DGL. If not, see <http://www.gnu.org/licenses/>.
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+
+#define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0])
+
+//Serial pc(USBTX,USBRX);
+
+
+//******************************************************************************************************
+uLCD_4DGL :: uLCD_4DGL(PinName tx, PinName rx, PinName rst) : _cmd(tx, rx),
+ _rst(rst)
+#if DEBUGMODE
+ ,pc(USBTX, USBRX)
+#endif // DEBUGMODE
+{
+ // Constructor
+ _cmd.baud(9600);
+#if DEBUGMODE
+ pc.baud(115200);
+
+ pc.printf("\n\n\n");
+ pc.printf("*********************\n");
+ pc.printf("uLCD_4DGL CONSTRUCTOR\n");
+ pc.printf("*********************\n");
+#endif
+
+ _rst = 1; // put RESET pin to high to start TFT screen
+ reset();
+ cls(); // clear screen
+ current_col = 0; // initial cursor col
+ current_row = 0; // initial cursor row
+ current_color = WHITE; // initial text color
+ current_orientation = IS_PORTRAIT; // initial screen orientation
+ current_hf = 1;
+ current_wf = 1;
+ set_font(FONT_7X8); // initial font
+// text_mode(OPAQUE); // initial texr mode
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: writeBYTE(char c) // send a BYTE command to screen
+{
+
+ _cmd.putc(c);
+ wait_us(500); //mbed is too fast for LCD at high baud rates in some long commands
+
+#if DEBUGMODE
+ pc.printf(" Char sent : 0x%02X\n",c);
+#endif
+
+}
+
+//******************************************************************************************************
+void uLCD_4DGL :: writeBYTEfast(char c) // send a BYTE command to screen
+{
+
+ _cmd.putc(c);
+ //wait_ms(0.0); //mbed is too fast for LCD at high baud rates - but not in short commands
+
+#if DEBUGMODE
+ pc.printf(" Char sent : 0x%02X\n",c);
+#endif
+
+}
+//******************************************************************************************************
+void uLCD_4DGL :: freeBUFFER(void) // Clear serial buffer before writing command
+{
+
+ while (_cmd.readable()) _cmd.getc(); // clear buffer garbage
+}
+
+//******************************************************************************************************
+int uLCD_4DGL :: writeCOMMAND(char *command, int number) // send several BYTES making a command and return an answer
+{
+
+#if DEBUGMODE
+ pc.printf("\n");
+ pc.printf("New COMMAND : 0x%02X\n", command[0]);
+#endif
+ int i, resp = 0;
+ freeBUFFER();
+ writeBYTE(0xFF);
+ for (i = 0; i < number; i++) {
+ if (i<16)
+ writeBYTEfast(command[i]); // send command to serial port
+ else
+ writeBYTE(command[i]); // send command to serial port but slower
+ }
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) resp = _cmd.getc(); // read response if any
+ switch (resp) {
+ case ACK : // if OK return 1
+ resp = 1;
+ break;
+ case NAK : // if NOK return -1
+ resp = -1;
+ break;
+ default :
+ resp = 0; // else return 0
+ break;
+ }
+#if DEBUGMODE
+ pc.printf(" Answer received : %d\n",resp);
+#endif
+
+ return resp;
+}
+
+//**************************************************************************
+void uLCD_4DGL :: reset() // Reset Screen
+{
+ wait_ms(5);
+ _rst = 0; // put RESET pin to low
+ wait_ms(5); // wait a few milliseconds for command reception
+ _rst = 1; // put RESET back to high
+ wait(3); // wait 3s for screen to restart
+
+ freeBUFFER(); // clean buffer from possible garbage
+}
+//******************************************************************************************************
+int uLCD_4DGL :: writeCOMMANDnull(char *command, int number) // send several BYTES making a command and return an answer
+{
+
+#if DEBUGMODE
+ pc.printf("\n");
+ pc.printf("New COMMAND : 0x%02X\n", command[0]);
+#endif
+ int i, resp = 0;
+ freeBUFFER();
+ writeBYTE(0x00); //command has a null prefix byte
+ for (i = 0; i < number; i++) {
+ if (i<16) //don't overflow LCD UART buffer
+ writeBYTEfast(command[i]); // send command to serial port
+ else
+ writeBYTE(command[i]); // send command to serial port with delay
+ }
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+ if (_cmd.readable()) resp = _cmd.getc(); // read response if any
+ switch (resp) {
+ case ACK : // if OK return 1
+ resp = 1;
+ break;
+ case NAK : // if NOK return -1
+ resp = -1;
+ break;
+ default :
+ resp = 0; // else return 0
+ break;
+ }
+#if DEBUGMODE
+ pc.printf(" Answer received : %d\n",resp);
+#endif
+
+ return resp;
+}
+
+//**************************************************************************
+void uLCD_4DGL :: cls() // clear screen
+{
+ char command[1] = "";
+
+ command[0] = CLS;
+ writeCOMMAND(command, 1);
+ current_row=0;
+ current_col=0;
+ current_hf = 1;
+ current_wf = 1;
+ set_font(FONT_7X8); // initial font
+}
+
+//**************************************************************************
+int uLCD_4DGL :: version() // get API version
+{
+
+ char command[2] = "";
+ command[0] = '\x00';
+ command[1] = VERSION;
+ return readVERSION(command, 2);
+}
+
+//**************************************************************************
+void uLCD_4DGL :: baudrate(int speed) // set screen baud rate
+{
+ char command[3]= "";
+ writeBYTE(0x00);
+ command[0] = BAUDRATE;
+ command[1] = 0;
+ int newbaud = BAUD_9600;
+ switch (speed) {
+ case 110 :
+ newbaud = BAUD_110;
+ break;
+ case 300 :
+ newbaud = BAUD_300;
+ break;
+ case 600 :
+ newbaud = BAUD_600;
+ break;
+ case 1200 :
+ newbaud = BAUD_1200;
+ break;
+ case 2400 :
+ newbaud = BAUD_2400;
+ break;
+ case 4800 :
+ newbaud = BAUD_4800;
+ break;
+ case 9600 :
+ newbaud = BAUD_9600;
+ break;
+ case 14400 :
+ newbaud = BAUD_14400;
+ break;
+ case 19200 :
+ newbaud = BAUD_19200;
+ break;
+ case 31250 :
+ newbaud = BAUD_31250;
+ break;
+ case 38400 :
+ newbaud = BAUD_38400;
+ break;
+ case 56000 :
+ newbaud = BAUD_56000;
+ break;
+ case 57600 :
+ newbaud = BAUD_57600;
+ break;
+ case 115200 :
+ newbaud = BAUD_115200;
+ break;
+ case 128000 :
+ newbaud = BAUD_128000;
+ break;
+ case 256000 :
+ newbaud = BAUD_256000;
+ break;
+ case 300000 :
+ newbaud = BAUD_300000;
+ speed = 272727;
+ break;
+ case 375000 :
+ newbaud = BAUD_375000;
+ speed = 333333;
+ break;
+ case 500000 :
+ newbaud = BAUD_500000;
+ speed = 428571;
+ break;
+ case 600000 :
+ newbaud = BAUD_600000;
+ break;
+ case 750000 : //rates over 600000 are not documented, but seem to work
+ newbaud = BAUD_750000;
+ break;
+ case 1000000 :
+ newbaud = BAUD_1000000;
+ break;
+ case 1500000 :
+ newbaud = BAUD_1500000;
+ break;
+ case 3000000 :
+ newbaud = BAUD_3000000;
+ break;
+ default :
+ newbaud = BAUD_9600;
+ speed = 9600;
+ break;
+ }
+
+ int i, resp = 0;
+
+ freeBUFFER();
+ command[1] = char(newbaud >>8);
+ command[2] = char(newbaud % 256);
+ wait_ms(1);
+ for (i = 0; i <3; i++) writeBYTEfast(command[i]); // send command to serial port
+ for (i = 0; i<10; i++) wait_ms(1);
+ //dont change baud until all characters get sent out
+ _cmd.baud(speed); // set mbed to same speed
+ i=0;
+ while ((!_cmd.readable()) && (i<25000)) {
+ wait_ms(TEMPO); // wait for screen answer - comes 100ms after change
+ i++; //timeout if ack character missed by baud change
+ }
+ if (_cmd.readable()) resp = _cmd.getc(); // read response if any
+ switch (resp) {
+ case ACK : // if OK return 1
+ resp = 1;
+ break;
+ case NAK : // if NOK return -1
+ resp = -1;
+ break;
+ default :
+ resp = 0; // else return 0
+ break;
+ }
+}
+
+//******************************************************************************************************
+int uLCD_4DGL :: readVERSION(char *command, int number) // read screen info and populate data
+{
+
+ int i, temp = 0, resp = 0;
+ char response[5] = "";
+
+ freeBUFFER();
+
+ for (i = 0; i < number; i++) writeBYTE(command[i]); // send all chars to serial port
+
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+
+ while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
+ temp = _cmd.getc();
+ response[resp++] = (char)temp;
+ }
+ switch (resp) {
+ case 2 : // if OK populate data and return 1
+ revision = response[0]<<8 + response[1];
+ resp = 1;
+ break;
+ default :
+ resp = 0; // else return 0
+ break;
+ }
+ return resp;
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: background_color(int color) // set screen background color
+{
+ char command[3]= ""; // input color is in 24bits like 0xRRGGBB
+
+ command[0] = BCKGDCOLOR;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: textbackground_color(int color) // set screen background color
+{
+ char command[3]= ""; // input color is in 24bits like 0xRRGGBB
+
+ command[0] = TXTBCKGDCOLOR;
+
+ int red5 = (color >> (16 + 3)) & 0x1F; // get red on 5 bits
+ int green6 = (color >> (8 + 2)) & 0x3F; // get green on 6 bits
+ int blue5 = (color >> (0 + 3)) & 0x1F; // get blue on 5 bits
+
+ command[1] = ((red5 << 3) + (green6 >> 3)) & 0xFF; // first part of 16 bits color
+ command[2] = ((green6 << 5) + (blue5 >> 0)) & 0xFF; // second part of 16 bits color
+
+ writeCOMMAND(command, 3);
+}
+
+//****************************************************************************************************
+void uLCD_4DGL :: display_control(char mode) // set screen mode to value
+{
+ char command[3]= "";
+
+ command[0] = DISPCONTROL;
+ command[1] = 0;
+ command[2] = mode;
+
+ if (mode == ORIENTATION) {
+ switch (mode) {
+ case LANDSCAPE :
+ current_orientation = IS_LANDSCAPE;
+ break;
+ case LANDSCAPE_R :
+ current_orientation = IS_LANDSCAPE;
+ break;
+ case PORTRAIT :
+ current_orientation = IS_PORTRAIT;
+ break;
+ case PORTRAIT_R :
+ current_orientation = IS_PORTRAIT;
+ break;
+ }
+ }
+ writeCOMMAND(command, 3);
+ set_font(current_font);
+}
+//****************************************************************************************************
+void uLCD_4DGL :: display_power(char mode) // set screen mode to value
+{
+ char command[3]= "";
+
+ command[0] = DISPPOWER;
+ command[1] = 0;
+ command[2] = mode;
+ writeCOMMAND(command, 3);
+}
+//****************************************************************************************************
+void uLCD_4DGL :: set_volume(char value) // set sound volume to value
+{
+ char command[2]= "";
+
+ command[0] = SETVOLUME;
+ command[1] = value;
+
+ writeCOMMAND(command, 2);
+}
+
+
+//******************************************************************************************************
+int uLCD_4DGL :: getSTATUS(char *command, int number) // read screen info and populate data
+{
+
+#if DEBUGMODE
+ pc.printf("\n");
+ pc.printf("New COMMAND : 0x%02X\n", command[0]);
+#endif
+
+ int i, temp = 0, resp = 0;
+ char response[5] = "";
+
+ freeBUFFER();
+
+ for (i = 0; i < number; i++) writeBYTE(command[i]); // send all chars to serial port
+
+ while (!_cmd.readable()) wait_ms(TEMPO); // wait for screen answer
+
+ while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
+ temp = _cmd.getc();
+ response[resp++] = (char)temp;
+ }
+ switch (resp) {
+ case 4 :
+ resp = (int)response[1]; // if OK populate data
+ break;
+ default :
+ resp = -1; // else return 0
+ break;
+ }
+
+#if DEBUGMODE
+ pc.printf(" Answer received : %d\n", resp);
+#endif
+
+ return resp;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ultrasonic.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,92 @@
+ #include "ultrasonic.h"
+
+ ultrasonic::ultrasonic(PinName trigPin, PinName echoPin, float updateSpeed, float timeout):_trig(trigPin), _echo(echoPin)
+ {
+ _updateSpeed = updateSpeed;
+ _timeout = timeout;
+ }
+
+ ultrasonic::ultrasonic(PinName trigPin, PinName echoPin, float updateSpeed, float timeout, void onUpdate(int))
+ :_trig(trigPin), _echo(echoPin)
+ {
+ _onUpdateMethod=onUpdate;
+ _updateSpeed = updateSpeed;
+ _timeout = timeout;
+ _t.start ();
+ }
+ void ultrasonic::_startT()
+ {
+ if(_t.read()>600)
+ {
+ _t.reset ();
+ }
+ start = _t.read_us ();
+ }
+
+ void ultrasonic::_updateDist()
+ {
+ end = _t.read_us ();
+ done = 1;
+ _distance = (end - start)/6;
+ _tout.detach();
+ _tout.attach(this,&ultrasonic::_startTrig, _updateSpeed);
+ }
+ void ultrasonic::_startTrig(void)
+ {
+ _tout.detach();
+ _trig=1;
+ wait_us(10);
+ done = 0;
+ _echo.rise(this,&ultrasonic::_startT);
+ _echo.fall(this,&ultrasonic::_updateDist);
+ _echo.enable_irq ();
+ _tout.attach(this,&ultrasonic::_startTrig,_timeout);
+ _trig=0;
+ }
+
+ int ultrasonic::getCurrentDistance(void)
+ {
+ return _distance;
+ }
+ void ultrasonic::pauseUpdates(void)
+ {
+ _tout.detach();
+ _echo.rise(NULL);
+ _echo.fall(NULL);
+ }
+ void ultrasonic::startUpdates(void)
+ {
+ _startTrig();
+ }
+ void ultrasonic::attachOnUpdate(void method(int))
+ {
+ _onUpdateMethod = method;
+ }
+ void ultrasonic::changeUpdateSpeed(float updateSpeed)
+ {
+ _updateSpeed = updateSpeed;
+ }
+ float ultrasonic::getUpdateSpeed()
+ {
+ return _updateSpeed;
+ }
+ int ultrasonic::isUpdated(void)
+ {
+ /****ADDED CODE ****/
+ if (_distance <= 50) {
+ d = 1;
+ } else {
+ d = 0;
+ }
+ /******************/
+ //d=done;
+ done = 0;
+ return d;
+ }
+ void ultrasonic::checkDistance(void)
+ {
+ if(isUpdated())
+ {
+ (*_onUpdateMethod)(_distance);
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ultrasonic.h Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,47 @@
+#ifndef MBED_ULTRASONIC_H
+#define MBED_ULTRASONIC_H
+
+#include "mbed.h"
+
+class ultrasonic
+{
+ public:
+ /**iniates the class with the specified trigger pin, echo pin, update speed and timeout**/
+ ultrasonic(PinName trigPin, PinName echoPin, float updateSpeed, float timeout);
+ /**iniates the class with the specified trigger pin, echo pin, update speed, timeout and method to call when the distance changes**/
+ ultrasonic(PinName trigPin, PinName echoPin, float updateSpeed, float timeout, void onUpdate(int));
+ /** returns the last measured distance**/
+ int getCurrentDistance(void);
+ /**pauses measuring the distance**/
+ void pauseUpdates(void);
+ /**starts mesuring the distance**/
+ void startUpdates(void);
+ /**attachs the method to be called when the distances changes**/
+ void attachOnUpdate(void method(int));
+ /**changes the speed at which updates are made**/
+ void changeUpdateSpeed(float updateSpeed);
+ /**gets whether the distance has been changed since the last call of isUpdated() or checkDistance()**/
+ int isUpdated(void);
+ /**gets the speed at which updates are made**/
+ float getUpdateSpeed(void);
+ /**call this as often as possible in your code, eg. at the end of a while(1) loop,
+ and it will check whether the method you have attached needs to be called**/
+ void checkDistance(void);
+ private:
+ DigitalOut _trig;
+ InterruptIn _echo;
+ Timer _t;
+ Timeout _tout;
+ int _distance;
+ float _updateSpeed;
+ int start;
+ int end;
+ volatile int done;
+ void (*_onUpdateMethod)(int);
+ void _startT(void);
+ void _updateDist(void);
+ void _startTrig(void);
+ float _timeout;
+ int d;
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wave_player/wave_player.cpp Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,211 @@
+//-----------------------------------------------------------------------------
+// a sample mbed library to play back wave files.
+//
+// explanation of wave file format.
+// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
+
+// if VERBOSE is uncommented then the wave player will enter a verbose
+// mode that displays all data values as it reads them from the file
+// and writes them to the DAC. Very slow and unusable output on the DAC,
+// but useful for debugging wave files that don't work.
+//#define VERBOSE
+
+
+#include <mbed.h>
+#include <stdio.h>
+#include <wave_player.h>
+
+
+//-----------------------------------------------------------------------------
+// constructor -- accepts an mbed pin to use for AnalogOut. Only p18 will work
+wave_player::wave_player(AnalogOut *_dac)
+{
+ wave_DAC=_dac;
+ wave_DAC->write_u16(32768); //DAC is 0-3.3V, so idles at ~1.6V
+ verbosity=0;
+}
+
+//-----------------------------------------------------------------------------
+// if verbosity is set then wave player enters a mode where the wave file
+// is decoded and displayed to the screen, including sample values put into
+// the DAC FIFO, and values read out of the DAC FIFO by the ISR. The DAC output
+// itself is so slow as to be unusable, but this might be handy for debugging
+// wave files that don't play
+//-----------------------------------------------------------------------------
+void wave_player::set_verbosity(int v)
+{
+ verbosity=v;
+}
+
+//-----------------------------------------------------------------------------
+// player function. Takes a pointer to an opened wave file. The file needs
+// to be stored in a filesystem with enough bandwidth to feed the wave data.
+// LocalFileSystem isn't, but the SDcard is, at least for 22kHz files. The
+// SDcard filesystem can be hotrodded by increasing the SPI frequency it uses
+// internally.
+//-----------------------------------------------------------------------------
+void wave_player::play(FILE *wavefile)
+{
+ unsigned chunk_id,chunk_size,channel;
+ unsigned data,samp_int,i;
+ short unsigned dac_data;
+ long long slice_value;
+ char *slice_buf;
+ short *data_sptr;
+ unsigned char *data_bptr;
+ int *data_wptr;
+ FMT_STRUCT wav_format;
+ long slice,num_slices;
+ DAC_wptr=0;
+ DAC_rptr=0;
+ for (i=0;i<256;i+=2) {
+ DAC_fifo[i]=0;
+ DAC_fifo[i+1]=3000;
+ }
+ DAC_wptr=4;
+ DAC_on=0;
+
+ fread(&chunk_id,4,1,wavefile);
+ fread(&chunk_size,4,1,wavefile);
+ while (!feof(wavefile)) {
+ if (verbosity)
+ printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size);
+ switch (chunk_id) {
+ case 0x46464952:
+ fread(&data,4,1,wavefile);
+ if (verbosity) {
+ printf("RIFF chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" RIFF type 0x%x\n",data);
+ }
+ break;
+ case 0x20746d66:
+ fread(&wav_format,sizeof(wav_format),1,wavefile);
+ if (verbosity) {
+ printf("FORMAT chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" compression code %d\n",wav_format.comp_code);
+ printf(" %d channels\n",wav_format.num_channels);
+ printf(" %d samples/sec\n",wav_format.sample_rate);
+ printf(" %d bytes/sec\n",wav_format.avg_Bps);
+ printf(" block align %d\n",wav_format.block_align);
+ printf(" %d bits per sample\n",wav_format.sig_bps);
+ }
+ if (chunk_size > sizeof(wav_format))
+ fseek(wavefile,chunk_size-sizeof(wav_format),SEEK_CUR);
+ break;
+ case 0x61746164:
+// allocate a buffer big enough to hold a slice
+ slice_buf=(char *)malloc(wav_format.block_align);
+ if (!slice_buf) {
+ printf("Unable to malloc slice buffer");
+ exit(1);
+ }
+ num_slices=chunk_size/wav_format.block_align;
+ samp_int=1000000/(wav_format.sample_rate);
+ if (verbosity) {
+ printf("DATA chunk\n");
+ printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
+ printf(" %d slices\n",num_slices);
+ printf(" Ideal sample interval=%d\n",(unsigned)(1000000.0/wav_format.sample_rate));
+ printf(" programmed interrupt tick interval=%d\n",samp_int);
+ }
+
+// starting up ticker to write samples out -- no printfs until tick.detach is called
+ if (verbosity)
+ tick.attach_us(this,&wave_player::dac_out, 500000);
+ else
+ tick.attach_us(this,&wave_player::dac_out, samp_int);
+ DAC_on=1;
+
+// start reading slices, which contain one sample each for however many channels
+// are in the wave file. one channel=mono, two channels=stereo, etc. Since
+// mbed only has a single AnalogOut, all of the channels present are averaged
+// to produce a single sample value. This summing and averaging happens in
+// a variable of type signed long long, to make sure that the data doesn't
+// overflow regardless of sample size (8 bits, 16 bits, 32 bits).
+//
+// note that from what I can find that 8 bit wave files use unsigned data,
+// while 16 and 32 bit wave files use signed data
+//
+ for (slice=0;slice<num_slices;slice+=1) {
+ fread(slice_buf,wav_format.block_align,1,wavefile);
+ if (feof(wavefile)) {
+ printf("Oops -- not enough slices in the wave file\n");
+ exit(1);
+ }
+ data_sptr=(short *)slice_buf; // 16 bit samples
+ data_bptr=(unsigned char *)slice_buf; // 8 bit samples
+ data_wptr=(int *)slice_buf; // 32 bit samples
+ slice_value=0;
+ for (channel=0;channel<wav_format.num_channels;channel++) {
+ switch (wav_format.sig_bps) {
+ case 16:
+ if (verbosity)
+ printf("16 bit channel %d data=%d ",channel,data_sptr[channel]);
+ slice_value+=data_sptr[channel];
+ break;
+ case 32:
+ if (verbosity)
+ printf("32 bit channel %d data=%d ",channel,data_wptr[channel]);
+ slice_value+=data_wptr[channel];
+ break;
+ case 8:
+ if (verbosity)
+ printf("8 bit channel %d data=%d ",channel,(int)data_bptr[channel]);
+ slice_value+=data_bptr[channel];
+ break;
+ }
+ }
+ slice_value/=wav_format.num_channels;
+
+// slice_value is now averaged. Next it needs to be scaled to an unsigned 16 bit value
+// with DC offset so it can be written to the DAC.
+ switch (wav_format.sig_bps) {
+ case 8: slice_value<<=8;
+ break;
+ case 16: slice_value+=32768;
+ break;
+ case 32: slice_value>>=16;
+ slice_value+=32768;
+ break;
+ }
+ dac_data=(short unsigned)slice_value;
+ if (verbosity)
+ printf("sample %d wptr %d slice_value %d dac_data %u\n",slice,DAC_wptr,(int)slice_value,dac_data);
+ DAC_fifo[DAC_wptr]=dac_data;
+ DAC_wptr=(DAC_wptr+1) & 0xff;
+ while (DAC_wptr==DAC_rptr) {
+ }
+ }
+ DAC_on=0;
+ tick.detach();
+ free(slice_buf);
+ break;
+ case 0x5453494c:
+ if (verbosity)
+ printf("INFO chunk, size %d\n",chunk_size);
+ fseek(wavefile,chunk_size,SEEK_CUR);
+ break;
+ default:
+ printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size);
+ data=fseek(wavefile,chunk_size,SEEK_CUR);
+ break;
+ }
+ fread(&chunk_id,4,1,wavefile);
+ fread(&chunk_size,4,1,wavefile);
+ }
+}
+
+
+void wave_player::dac_out()
+{
+ if (DAC_on) {
+#ifdef VERBOSE
+ printf("ISR rdptr %d got %u\n",DAC_rptr,DAC_fifo[DAC_rptr]);
+#endif
+ wave_DAC->write_u16(DAC_fifo[DAC_rptr]);
+ DAC_rptr=(DAC_rptr+1) & 0xff;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wave_player/wave_player.h Thu Apr 30 00:27:23 2020 +0000
@@ -0,0 +1,72 @@
+#include <mbed.h>
+
+typedef struct uFMT_STRUCT {
+ short comp_code;
+ short num_channels;
+ unsigned sample_rate;
+ unsigned avg_Bps;
+ short block_align;
+ short sig_bps;
+} FMT_STRUCT;
+
+
+/** wave file player class.
+ *
+ * Example:
+ * @code
+ * #include <mbed.h>
+ * #include <wave_player.h>
+ *
+ * AnalogOut DACout(p18);
+ * wave_player waver(&DACout);
+ *
+ * int main() {
+ * FILE *wave_file;
+ *
+ * printf("\n\n\nHello, wave world!\n");
+ * wave_file=fopen("/sd/44_8_st.wav","r");
+ * waver.play(wave_file);
+ * fclose(wave_file);
+ * }
+ * @endcode
+ */
+class wave_player {
+
+public:
+/** Create a wave player using a pointer to the given AnalogOut object.
+ *
+ * @param _dac pointer to an AnalogOut object to which the samples are sent.
+ */
+wave_player(AnalogOut *_dac);
+
+/** the player function.
+ *
+ * @param wavefile A pointer to an opened wave file
+ */
+void play(FILE *wavefile);
+
+/** Set the printf verbosity of the wave player. A nonzero verbosity level
+ * will put wave_player in a mode where the complete contents of the wave
+ * file are echoed to the screen, including header values, and including
+ * all of the sample values placed into the DAC FIFO, and the sample values
+ * removed from the DAC FIFO by the ISR. The sample output frequency is
+ * fixed at 2 Hz in this mode, so it's all very slow and the DAC output isn't
+ * very useful, but it lets you see what's going on and may help for debugging
+ * wave files that don't play correctly.
+ *
+ * @param v the verbosity level
+ */
+void set_verbosity(int v);
+
+private:
+void dac_out(void);
+int verbosity;
+AnalogOut *wave_DAC;
+Ticker tick;
+unsigned short DAC_fifo[256];
+short DAC_wptr;
+volatile short DAC_rptr;
+short DAC_on;
+};
+
+