Skip to content

Commit

Permalink
First draft of high-level API for controlling various DIOs.
Browse files Browse the repository at this point in the history
This works, but needs refinement and extension.
  • Loading branch information
aentinger committed Mar 27, 2024
1 parent b8f7e9a commit 804d549
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 1 deletion.
115 changes: 115 additions & 0 deletions examples/tools/Control-DIOx/Control-DIOx.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* This example has been tested with the Arduino 10BASE-T1S (T1TOS) shield and
* can be used to control the value of various DIO output pins.
*
* Author:
* Alexander Entinger
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <Arduino_10BASE_T1S.h>

#include <SPI.h>

/**************************************************************************************
* CONSTANTS
**************************************************************************************/

static uint8_t const T1S_PLCA_NODE_ID = 0; /* Doubles as PLCA coordinator. */

static IPAddress const ip_addr {192, 168, 42, 100 + T1S_PLCA_NODE_ID};
static IPAddress const network_mask{255, 255, 255, 0};
static IPAddress const gateway {192, 168, 42, 100};

static T1SPlcaSettings const t1s_plca_settings{T1S_PLCA_NODE_ID};
static T1SMacSettings const t1s_default_mac_settings;

/**************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************/

auto const tc6_io = new TC6::TC6_Io
( SPI
, CS_PIN
, RESET_PIN
, IRQ_PIN);
auto const tc6_inst = new TC6::TC6_Arduino_10BASE_T1S(tc6_io);

/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/

void setup()
{
Serial.begin(115200);
while (!Serial) { }
delay(1000);

/* Initialize digital IO interface for interfacing
* with the LAN8651.
*/
pinMode(IRQ_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(IRQ_PIN),
[]() { tc6_io->onInterrupt(); },
FALLING);

/* Initialize IO module. */
if (!tc6_io->begin())
{
Serial.println("'TC6_Io::begin(...)' failed.");
for (;;) { }
}

MacAddress const mac_addr = MacAddress::create_from_uid();

if (!tc6_inst->begin(ip_addr
, network_mask
, gateway
, mac_addr
, t1s_plca_settings
, t1s_default_mac_settings))
{
Serial.println("'TC6::begin(...)' failed.");
for (;;) { }
}

Serial.print("IP\t");
Serial.println(ip_addr);
Serial.println(mac_addr);
Serial.println(t1s_plca_settings);
Serial.println(t1s_default_mac_settings);

// If Power Provider, turn on LOCAL_ENABLE and turn on T1S_DISABLE
//tc6_inst->digitalWrite(1,1,1);
//tc6_inst->digitalWrite(0,0,0);
}

void loop()
{
/* Services the hardware and the protocol stack.
* Must be called cyclic. The faster the better.
*/
tc6_inst->service();

static unsigned long prev_dio_toogle = 0;
auto const now = millis();

if ((now - prev_dio_toogle) > 5000)
{
prev_dio_toogle = now;

static bool dio_val = true;

Serial.print("DIO A0 = ");
Serial.println(dio_val);

/* Modify this function call parameter if you want
* to test a different LAN8651 DIO.
*/
tc6_inst->digitalWrite(TC6::DIO::A0, dio_val);
dio_val = !dio_val;
}
}
23 changes: 23 additions & 0 deletions src/microchip/TC6_Arduino_10BASE_T1S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ void TC6_Arduino_10BASE_T1S::digitalWrite(bool dioa0, bool dioa1, bool dioa2)
TC6Regs_SetDio(_lw.tc.tc6, dioa0, dioa1, dioa2);
}

void TC6_Arduino_10BASE_T1S::digitalWrite(DIO const dio, bool const value)
{
if (dio == DIO::A0)
digitalWrite_A0(value);
}

void TC6_Arduino_10BASE_T1S::service()
{
sys_check_timeouts(); /* LWIP timers - ARP, DHCP, TCP, etc. */
Expand Down Expand Up @@ -237,6 +243,23 @@ bool TC6_Arduino_10BASE_T1S::sendWouldBlock()
return wouldBlock;
}

void TC6_Arduino_10BASE_T1S::digitalWrite_A0(bool const value)
{
static bool is_dio_a0_enabled = false;
if (!is_dio_a0_enabled)
{
TC6Regs_EnableDio_A0(_lw.tc.tc6);
is_dio_a0_enabled = true;
}

static bool dio_a0_val = false;
if (value != dio_a0_val)
{
TC6Regs_ToggleDio_A0(_lw.tc.tc6);
dio_a0_val = value;
}
}

/**************************************************************************************
* LWIP CALLBACKS
**************************************************************************************/
Expand Down
10 changes: 10 additions & 0 deletions src/microchip/TC6_Arduino_10BASE_T1S.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ typedef struct
namespace TC6
{

/**************************************************************************************
* TYPEDEF
**************************************************************************************/

enum class DIO { A0, A1, A2, A3, A4, B0 };

/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/
Expand All @@ -85,6 +91,8 @@ class TC6_Arduino_10BASE_T1S : public Arduino_10BASE_T1S_PHY_Interface

void digitalWrite(bool dioa0, bool dioa1, bool dioa2);

void digitalWrite(DIO const dio, bool const value);

bool getPlcaStatus(TC6LwIP_On_PlcaStatus on_plca_status);
bool enablePlca();

Expand All @@ -95,6 +103,8 @@ class TC6_Arduino_10BASE_T1S : public Arduino_10BASE_T1S_PHY_Interface
TC6_Io * _tc6_io;
TC6LwIP_t _lw;
T1SPlcaSettings _t1s_plca_settings;

void digitalWrite_A0(bool const value);
};

/**************************************************************************************
Expand Down
40 changes: 39 additions & 1 deletion src/microchip/lib/libtc6/inc/tc6-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Microchip or any third party.
#include <stdint.h>
#include "tc6.h"

#include <type_traits>

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* DEFINITIONS */
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
Expand Down Expand Up @@ -82,6 +84,18 @@ typedef enum
TC6Regs_Event_Unsupported_Hardware
} TC6Regs_Event_t;

enum class PADCTRL_A0SEL : uint32_t
{
EVENT_CAPTURE = 0x00,
EVENT_GENERATOR_0 = 0x01
};
constexpr uint32_t PADCTRL_A0SEL_MASK = 0x00000003;

enum class EG0CTL : uint32_t
{
START = 0,
};

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* PUBLIC API */
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
Expand Down Expand Up @@ -128,6 +142,8 @@ bool TC6Regs_SetPlca(TC6_t *pInst, bool plcaEnable, uint8_t nodeId, uint8_t node
*/
bool TC6Regs_SetDio(TC6_t *pTC6, bool dioa0, bool dioa1, bool dioa2);

void TC6Regs_EnableDio_A0(TC6_t *pTC6);
void TC6Regs_ToggleDio_A0(TC6_t *pTC6);

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Implementation of TC6 Callback */
Expand Down Expand Up @@ -159,6 +175,28 @@ uint32_t TC6Regs_CB_GetTicksMs(void);
* \param event - Enumeration matching to the occured event.
* \param pTag - The exact same pointer, which was given along with the TC6Regs_Init() function.
*/
void TC6Regs_CB_OnEvent(TC6_t *pInst, TC6Regs_Event_t event, void *pTag);
void TC6Regs_CB_OnEvent(TC6_t *pInst, TC6Regs_Event_t event, void *pTag);

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* CONVERSTION FUNCTIONS */
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/

template <typename Enumeration>
constexpr auto to_integer(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}

template <typename Enumeration>
constexpr auto bp(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{
return to_integer(value);
}

template <typename Enumeration>
constexpr auto bm(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{
return (1 << to_integer(value));
}

#endif /* TC6_REGS_H_ */
34 changes: 34 additions & 0 deletions src/microchip/lib/libtc6/src/tc6-regs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,40 @@ bool TC6Regs_SetDio(TC6_t *pTC6, bool dioa0, bool dioa1, bool dioa2)
return true;
}

static bool is_dio_a0_op_done = false;
void TC6_Dio_A0_Callback(TC6_t *pInst, bool success, uint32_t addr, uint32_t value, void *pTag, void *pGlobalTag)
{
is_dio_a0_op_done = true;
}

void TC6Regs_EnableDio_A0(TC6_t *pTC6)
{
TC6Reg_t * pReg = GetContext(pTC6);

/* Configure as output, PADCTRL = 0x0088. */
uint32_t reg_val = to_integer(PADCTRL_A0SEL::EVENT_GENERATOR_0);
uint32_t reg_mask = PADCTRL_A0SEL_MASK;

is_dio_a0_op_done = false;
while (!is_dio_a0_op_done && !TC6_ReadModifyWriteRegister(pReg->pTC6, 0x000A0088, reg_val, reg_mask, CONTROL_PROTECTION, TC6_Dio_A0_Callback, NULL)) {
TC6_Service(pReg->pTC6, true);
}
}

void TC6Regs_ToggleDio_A0(TC6_t *pTC6)
{
TC6Reg_t * pReg = GetContext(pTC6);

/* Toggle output, EG0CTL = 0x0226. */
uint32_t reg_val = bm(EG0CTL::START);
uint32_t reg_mask = bm(EG0CTL::START);;

is_dio_a0_op_done = false;
while (!is_dio_a0_op_done && !TC6_ReadModifyWriteRegister(pReg->pTC6, 0x000A0226, reg_val, reg_mask, CONTROL_PROTECTION, TC6_Dio_A0_Callback, NULL)) {
TC6_Service(pReg->pTC6, true);
}
}

uint8_t TC6Regs_GetChipRevision(TC6_t *pTC6)
{
TC6Reg_t *pReg = GetContext(pTC6);
Expand Down

0 comments on commit 804d549

Please sign in to comment.