Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
microbit-carlos committed Apr 21, 2023
2 parents 940087e + ac74d3d commit f1de84c
Show file tree
Hide file tree
Showing 55 changed files with 2,334 additions and 495 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*~
*.swp
.vscode
.DS_Store
36 changes: 36 additions & 0 deletions inc/core/CodalComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ DEALINGS IN THE SOFTWARE.
#define DEVICE_ID_SYSTEM_ADC 34
#define DEVICE_ID_PULSE_IN 35
#define DEVICE_ID_USB 36
#define DEVICE_ID_SPLITTER 37
#define DEVICE_ID_AUDIO_PROCESSOR 38
#define DEVICE_ID_TAP 39
#define DEVICE_ID_POWER_MANAGER 40

// Slightly dubious IDs, moved here for now to remove conflicts
#define DEVICE_ID_PARTIAL_FLASHING 41
#define DEVICE_ID_USB_FLASH_MANAGER 42
#define DEVICE_ID_VIRTUAL_SPEAKER_PIN 43
#define DEVICE_ID_LOG 44

// Suggested range for device-specific IDs: 50-79
// NOTE - not final, just suggested currently.

// Range 80-99 - RESERVED (deprecated space, do not use!)

#define DEVICE_ID_IO_P0 100 // IDs 100-227 are reserved for I/O Pin IDs.

Expand All @@ -83,6 +98,9 @@ DEALINGS IN THE SOFTWARE.
// jacadac reserved from 3000 - 4000
#define DEVICE_ID_JD_DYNAMIC_ID 3000

// Range 64000-65000 RESERVED (dynamic ID space)
#define DEVICE_ID_DYNAMIC_MIN 64000
#define DEVICE_ID_DYNAMIC_MAX 65000

// Universal flags used as part of the status field
#define DEVICE_COMPONENT_RUNNING 0x1000
Expand Down Expand Up @@ -124,6 +142,24 @@ namespace codal
static uint8_t configuration;

public:
/**
* @brief Generates a new component ID from the dynamic block.
*
* There are some cases where multiple instances of the same component need unique IDs, this
* static method allows application code to request a safe (unused) globally unique ID for
* this purpose.
*
* This currently creates monotonically incrementing IDs, with no reuse. When they're gone
* they're gone!
*
* @note While currently monotonic, this may change in the future for more complex schemes.
*
* @note The dynamic block is a finite resource, and may eventually be exhausted causing a PANIC.
*
* @return uint16_t A new, unique component ID, until the ID space is exhausted.
*/
static uint16_t generateDynamicID();

/**
* Adds the current CodalComponent instance to our array of components.
*/
Expand Down
19 changes: 16 additions & 3 deletions inc/core/CodalConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,28 @@ DEALINGS IN THE SOFTWARE.
//
// Debug options
//
#ifndef DEVICE_DMESG
#define DEVICE_DMESG 0
#ifndef DMESG_SERIAL_DEBUG
#define DMESG_SERIAL_DEBUG 0
#else
// Automatically enable DMESG_ENABLE if DMESG_SERIAL_DEBUG is set
#if DMESG_SERIAL_DEBUG > 0
#define DMESG_ENABLE 1
#endif
#endif

#ifndef DMESG_ENABLE
#define DMESG_ENABLE 0
#endif

// When non-zero internal debug messages (DMESG() macro) go to a in-memory buffer of this size (in bytes).
// It can be inspected from GDB (with 'print codalLogStore'), or accessed by the application.
// Typical size range between 512 and 4096. Set to 0 to disable.
#ifndef DEVICE_DMESG_BUFFER_SIZE
#define DEVICE_DMESG_BUFFER_SIZE 1024
#if DMESG_ENABLE > 0
#define DEVICE_DMESG_BUFFER_SIZE 1024
#else
#define DEVICE_DMESG_BUFFER_SIZE 0
#endif
#endif

#ifndef CODAL_DEBUG
Expand Down
11 changes: 10 additions & 1 deletion inc/core/CodalFiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,13 @@ namespace codal
*/
FiberLock();

/**
* Create a new semaphore-mode lock that can be used for mutual exclusion and condition synchronisation.
*
* @param initial The number of access requests to grant before blocking
*/
FiberLock( int initial );

/**
* Block the calling fiber until the lock is available
**/
Expand All @@ -380,8 +387,10 @@ namespace codal

/**
* Release the lock, and signal to all waiting fibers to continue
*
* @param reset The number of slots to reinitialise the FiberLock to, for semaphore duty
*/
void notifyAll();
void notifyAll( int reset = 0 );

/**
* Determine the number of fibers currently blocked on this lock
Expand Down
8 changes: 6 additions & 2 deletions inc/core/ErrorNo.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,18 @@ enum PanicCode{
// Out out memory error. Heap storage was requested, but is not available.
DEVICE_OOM = 20,

// Device has run out of a finite resource. Dynamic IDs for example.
DEVICE_RESORUCES_EXHAUSTED = 21,

// Corruption detected in the codal device heap space
DEVICE_HEAP_ERROR = 30,

// Dereference of a NULL pointer through the ManagedType class,
DEVICE_NULL_DEREFERENCE = 40,

// Non-recoverable error in USB driver
DEVICE_USB_ERROR = 50,
// All ob-board peripheral failures should report from the 50-59 range, but may be device specific
// DO NOT USE ANYTHING BETWEEN 50 AND 60 HERE - used by implementing boards/libraries
DEVICE_PERIPHERAL_ERROR = 50,

// Non-recoverable error in the JACDAC stack
DEVICE_JACDAC_ERROR = 60,
Expand Down
3 changes: 3 additions & 0 deletions inc/driver-models/CodalUSB.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ class UsbEndpointIn
int clearStall();
int reset();
int write(const void *buf, int length);
#ifdef USB_EP_FLAG_ASYNC
bool canWrite();
#endif

UsbEndpointIn(uint8_t idx, uint8_t type, uint8_t size = USB_MAX_PKT_SIZE);
};
Expand Down
11 changes: 10 additions & 1 deletion inc/driver-models/I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace codal

enum AcknowledgeType {ACK, NACK};

class I2C
class I2C : public PinPeripheral
{
public:
I2C(Pin &sda, Pin &scl);
Expand Down Expand Up @@ -80,6 +80,15 @@ class I2C
virtual int read(AcknowledgeType ack = ACK);

public:
/**
* Change the pins used by this I2C peripheral to those provided.
*
* @param sda the Pin to use for the I2C SDA line.
* @param scl the Pin to use for the I2C SCL line.
* @return DEVICE_OK on success, or DEVICE_NOT_IMPLEMENTED / DEVICE_NOT_SUPPORTED if the request cannot be performed.
*/
virtual int redirect(Pin &sda, Pin &scl);

/**
* Issues a standard, 2 byte I2C command write to the I2C bus.
* This consists of:
Expand Down
4 changes: 2 additions & 2 deletions inc/driver-models/LowLevelTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ class LowLevelTimer : public CodalComponent
**/
virtual int setIRQPriority(int)
{
target_panic(DEVICE_NOT_IMPLEMENTED);
return DEVICE_NOT_IMPLEMENTED;
target_panic(DEVICE_HARDWARE_CONFIGURATION_ERROR);
return DEVICE_HARDWARE_CONFIGURATION_ERROR;
}

/**
Expand Down
21 changes: 21 additions & 0 deletions inc/driver-models/Pin.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ DEALINGS IN THE SOFTWARE.

#include "CodalConfig.h"
#include "CodalComponent.h"
#include "PinPeripheral.h"
// Status Field flags...
#define IO_STATUS_DIGITAL_IN 0x0001 // Pin is configured as a digital input, with no pull up.
#define IO_STATUS_DIGITAL_OUT 0x0002 // Pin is configured as a digital output
Expand All @@ -38,6 +39,7 @@ DEALINGS IN THE SOFTWARE.
#define IO_STATUS_INTERRUPT_ON_EDGE 0x0080 // Pin will generate events on pin change
#define IO_STATUS_ACTIVE_HI 0x0100 // Pin is ACTIVE_HI if set, or ACTIVE_LO if clear
#define IO_STATUS_WAKE_ON_ACTIVE 0x0200 // Pin should trigger power manager wake-up
#define IO_STATUS_DISCONNECTING 0x0400 // Pin is currently in the process of disconnecting from a peripheral

#define DEVICE_PIN_MAX_OUTPUT 1023

Expand All @@ -59,6 +61,7 @@ DEALINGS IN THE SOFTWARE.
namespace codal
{
using namespace codal;

/**
* Pin capabilities enum.
* Used to determine the capabilities of each Pin as some can only be digital, or can be both digital and analogue.
Expand Down Expand Up @@ -269,6 +272,17 @@ namespace codal
return (status & (IO_STATUS_ANALOG_IN | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1;
}

/**
* Determines if this IO pin is currently in the processing of being disconnected from a peripheral.
*
* @return 1 if pin is disconnecting, 0 otherwise.
*/
virtual int isDisconnecting()
{
return (status & IO_STATUS_DISCONNECTING) == 0 ? 0 : 1;
}


/**
* Configures this IO pin as a "makey makey" style touch sensor (if necessary)
* and tests its current debounced state.
Expand Down Expand Up @@ -531,6 +545,13 @@ namespace codal
return (status & IO_STATUS_WAKE_ON_ACTIVE) ? 1 : 0;
}

/**
* Record that a given peripheral has been connected to this pin.
*/
virtual void connect(PinPeripheral &p, bool deleteOnRelease = false)
{
p.deleteOnRelease = deleteOnRelease;
}
/**
* Disconnect any attached peripherals from this pin.
*/
Expand Down
87 changes: 87 additions & 0 deletions inc/driver-models/PinPeripheral.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
The MIT License (MIT)
Copyright (c) 2022 Lancaster University.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#ifndef PIN_PERIPHERAL_H
#define PIN_PERIPHERAL_H

#include "CodalConfig.h"
#include "CodalComponent.h"

namespace codal
{
/**
* Class definition for PinPeripheral.
*
* Serves as an abstract base class for any device driver that directly interacts with a Pin.
* Provides the necessary function to enable safe, dynamic rebinding of pins to peripherals at runtime
*/
class Pin;
class PinPeripheral
{
public:
bool deleteOnRelease = false;
bool pinLock = false;

/**
* Method to release the given pin from a peripheral, if already bound.
* Device drivers should override this method to disconnect themselves from the give pin
* to allow it to be used by a different peripheral.
*
* @param pin the Pin to be released
*/
virtual int releasePin(Pin &pin);

/**
* Determines if this peripheral has locked any attached pins to this peripheral.
* During a locked period, any attempts to release or reassign those pins to a differnet peripheral are ignored.
* This mechanism is primarily useful to use functions such as Pin::setDigitalValue() within a peripheral driver,
* but without releasing the pin's binding to that peripheral.
*
* @return true if this peripherals pin bindings are locked, false otherwise.
*/
bool isPinLocked();

/**
* Controls if this peripheral has locked any attached pins to this peripheral.
* During a locked period, any attempts to release or reassign those pins to a differnet peripheral are ignored.
* This mechanism is primarily useful to use functions such as Pin::setDigitalValue() within a peripheral driver,
* but without releasing the pin's binding to that peripheral.
*
* @param true if this peripherals pin bindings are to be locked, false otherwise.
*/
void setPinLock(bool locked);

/**
* Utility function, to assist in redirect() operations and consistent use of disconnect()/connect() by peripherals.
* Safely disconnects pin from any attached peripherals, upfates pin to the new pin, and attaches to the given peripheral.
* Also validates out NULL cases.
*
* @param pin Typically a mutable instance variable, holding the current pin used by a given peripheral.
* @param newPin The pin which is replacing the value of pin.
*/
int reassignPin(void *pin, Pin *newPin);
};
}

#endif
13 changes: 12 additions & 1 deletion inc/driver-models/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,20 @@ typedef void (*PVoidCallback)(void *);
/**
* Class definition for an SPI interface.
*/
class SPI
class SPI : public PinPeripheral
{
public:

/**
* Change the pins used by this I2C peripheral to those provided.
*
* @param mosi the Pin to use for the SPI input line.
* @param miso the Pin to use for the SPI output line.
* @param sclk the Pin to use for the SPI clock line.
* @return DEVICE_OK on success, or DEVICE_NOT_IMPLEMENTED / DEVICE_NOT_SUPPORTED if the request cannot be performed.
*/
virtual int redirect(Pin &mosi, Pin &miso, Pin &sclk);

/** Set the frequency of the SPI interface
*
* @param frequency The bus frequency in hertz
Expand Down
16 changes: 13 additions & 3 deletions inc/driver-models/Serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ namespace codal
*
* Represents an instance of RawSerial which accepts codal device specific data types.
*/
class Serial : public CodalComponent
class Serial : public PinPeripheral, public CodalComponent
{
protected:

Pin& tx;
Pin& rx;
Pin* tx;
Pin* rx;

//delimeters used for matching on receive.
ManagedString delimeters;
Expand Down Expand Up @@ -182,6 +182,11 @@ namespace codal
* gives a different behaviour:
*
* ASYNC - bytes are copied into the txBuff and returns immediately.
* If there is insufficient space in txBuff, then only the first 'n'
* bytes will actually be sent, refer to the return value to get
* how many bytes were actually put in the buffer.
* To ensure all bytes are sent on an ASYNC call, set an appropriate
* buffer length beforehand using setTxBufferSize.
*
* SYNC_SPINWAIT - bytes are copied into the txBuff and this method
* will spin (lock up the processor) until all bytes
Expand Down Expand Up @@ -210,6 +215,11 @@ namespace codal
* gives a different behaviour:
*
* ASYNC - bytes are copied into the txBuff and returns immediately.
* If there is insufficient space in txBuff, then only the first 'n'
* bytes will actually be sent, refer to the return value to get
* how many bytes were actually put in the buffer.
* To ensure all bytes are sent on an ASYNC call, set an appropriate
* buffer length beforehand using setTxBufferSize.
*
* SYNC_SPINWAIT - bytes are copied into the txBuff and this method
* will spin (lock up the processor) until all bytes
Expand Down
Loading

0 comments on commit f1de84c

Please sign in to comment.