-
Notifications
You must be signed in to change notification settings - Fork 253
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
introduce CRTKGpioDevice device class
Refactor the rtkgpio sample to use the CRTKGpioDevice class. Tested with the RTK.GPIO board.
- Loading branch information
Showing
6 changed files
with
386 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# | ||
# Makefile | ||
# | ||
|
||
CIRCLEHOME = ../.. | ||
|
||
OBJS = rtkgpio.o | ||
|
||
libgpio.a: $(OBJS) | ||
@echo " AR $@" | ||
@rm -f $@ | ||
@$(AR) cr $@ $(OBJS) | ||
|
||
include $(CIRCLEHOME)/Rules.mk | ||
|
||
-include $(DEPS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
// | ||
// rtkgpio.cpp | ||
// | ||
// Circle - A C++ bare metal environment for Raspberry Pi | ||
// Copyright (C) 2020 H. Kocevar <[email protected]> | ||
// | ||
// This program 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. | ||
// | ||
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | ||
// | ||
#include <circle/logger.h> | ||
#include "rtkgpio.h" | ||
|
||
static const char FromRtkgpio[] = "rtkgpio"; | ||
|
||
// Serial baudrate | ||
#define RTKGPIO_BAUD_RATE 230400 | ||
|
||
// Define the lowest and highest GPIO pin numbers | ||
#define RTKGPIO_PIN_MIN 0 | ||
#define RTKGPIO_PIN_MAX 27 | ||
|
||
CRTKGpioDevice::CRTKGpioDevice (CUSBSerialCH341Device *pCH341) | ||
: m_pCH341(pCH341) | ||
{ | ||
assert(m_pCH341 != 0); | ||
} | ||
|
||
CRTKGpioDevice::~CRTKGpioDevice () | ||
{ | ||
} | ||
|
||
boolean CRTKGpioDevice::Initialize (void) | ||
{ | ||
assert(m_pCH341 != 0); | ||
|
||
if (!m_pCH341->SetBaudRate (RTKGPIO_BAUD_RATE)) | ||
{ | ||
return FALSE; | ||
} | ||
|
||
if (!GetVersion ()) | ||
{ | ||
return FALSE; | ||
} | ||
|
||
return TRUE; | ||
} | ||
|
||
boolean CRTKGpioDevice::GetVersion (void) | ||
{ | ||
if (m_pCH341->Write ("V?", 2) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Write error V?"); | ||
|
||
return FALSE; | ||
} | ||
|
||
u8 rxData[32] = {0}; | ||
if (m_pCH341->Read (rxData, 32) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Read error version"); | ||
|
||
return FALSE; | ||
} | ||
|
||
CLogger::Get ()->Write (FromRtkgpio, LogDebug, "firmware version: %s", rxData); | ||
|
||
return TRUE; | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinDirectionOutput (unsigned nPin) | ||
{ | ||
return SetPinDirection (nPin, RtkGpioDirectionOutput); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinDirectionInput (unsigned nPin) | ||
{ | ||
return SetPinDirection (nPin, RtkGpioDirectionInput); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinPullNone(unsigned nPin) | ||
{ | ||
return SetPinPull (nPin, RtkGpioPullNone); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinPullDown (unsigned nPin) | ||
{ | ||
return SetPinPull (nPin, RtkGpioPullDown); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinPullUp (unsigned nPin) | ||
{ | ||
return SetPinPull (nPin, RtkGpioPullUp); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinLevelLow (unsigned nPin) | ||
{ | ||
return SetPinLevel (nPin, RtkGpioLevelLow); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinLevelHigh (unsigned nPin) | ||
{ | ||
return SetPinLevel (nPin, RtkGpioLevelHigh); | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinPull (unsigned nPin, TRtkGpioPull ePull) | ||
{ | ||
assert(nPin >= RTKGPIO_PIN_MIN && nPin <= RTKGPIO_PIN_MAX); | ||
|
||
u8 cmd[3] = {0}; | ||
cmd[0] = 'G'; | ||
cmd[1] = (u8)(nPin + 'a'); | ||
switch (ePull) { | ||
case RtkGpioPullNone: | ||
cmd[2] = 'N'; | ||
break; | ||
case RtkGpioPullDown: | ||
cmd[2] = 'D'; | ||
break; | ||
case RtkGpioPullUp: | ||
cmd[2] = 'U'; | ||
break; | ||
} | ||
|
||
if (m_pCH341->Write (cmd, sizeof (cmd)) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Failed to set pin %d pull", nPin); | ||
|
||
return FALSE; | ||
} | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Pin %d pull %s", nPin, | ||
// ePull == RtkGpioPullNone ? "none" : (ePull == RtkGpioPullDown ? "down" : "up")); | ||
|
||
return TRUE; | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinDirection (unsigned nPin, TRtkGpioDirection eDirection) | ||
{ | ||
assert(nPin >= RTKGPIO_PIN_MIN && nPin <= RTKGPIO_PIN_MAX); | ||
|
||
u8 cmd[3] = {0}; | ||
cmd[0] = 'G'; | ||
cmd[1] = (u8)(nPin + 'a'); | ||
switch (eDirection) { | ||
case RtkGpioDirectionOutput: | ||
cmd[2] = 'O'; | ||
break; | ||
case RtkGpioDirectionInput: | ||
cmd[2] = 'I'; | ||
break; | ||
} | ||
|
||
if (m_pCH341->Write (cmd, sizeof (cmd)) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Failed to set pin %d direction", nPin); | ||
|
||
return FALSE; | ||
} | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Pin %d direction %s", nPin, | ||
// eDirection == RtkGpioDirectionInput ? "input" : "output"); | ||
|
||
return TRUE; | ||
} | ||
|
||
boolean CRTKGpioDevice::SetPinLevel (unsigned nPin, TRtkGpioLevel eLevel) | ||
{ | ||
assert(nPin >= RTKGPIO_PIN_MIN && nPin <= RTKGPIO_PIN_MAX); | ||
|
||
u8 cmd[3] = {0}; | ||
cmd[0] = 'G'; | ||
cmd[1] = (u8)(nPin + 'a'); | ||
switch (eLevel) { | ||
case RtkGpioLevelLow: | ||
cmd[2] = '0'; | ||
break; | ||
case RtkGpioLevelHigh: | ||
cmd[2] = '1'; | ||
break; | ||
case RtkGpioLevelUnknown: | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Invalid pin %d level", nPin); | ||
return FALSE; | ||
break; | ||
} | ||
|
||
if (m_pCH341->Write (cmd, sizeof (cmd)) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Failed to set pin %d level", nPin); | ||
|
||
return FALSE; | ||
} | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Pin %d level %s", nPin, | ||
// eLevel == RtkGpioLevelLow ? "low" : "high"); | ||
|
||
return TRUE; | ||
} | ||
|
||
TRtkGpioLevel CRTKGpioDevice::GetPinLevel (unsigned nPin) | ||
{ | ||
assert(nPin >= RTKGPIO_PIN_MIN && nPin <= RTKGPIO_PIN_MAX); | ||
|
||
u8 cmd[3] = {0}; | ||
cmd[0] = 'G'; | ||
cmd[1] = (u8)(nPin + 'a'); | ||
cmd[2] = '?'; | ||
if (m_pCH341->Write (cmd, sizeof (cmd)) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Failed to get pin %d level", nPin); | ||
|
||
return RtkGpioLevelUnknown; | ||
} | ||
|
||
u8 rxData[4] = {0}; | ||
if (m_pCH341->Read (rxData, 4) < 0) | ||
{ | ||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Read error"); | ||
|
||
return RtkGpioLevelUnknown; | ||
} | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Read %s %2X %2X %2X %2X", | ||
// cmd, rxData[0], rxData[1], rxData[2], rxData[3]); | ||
|
||
switch (rxData[1]) { | ||
case '0': | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Pin %d level low", nPin); | ||
return RtkGpioLevelLow; | ||
break; | ||
case '1': | ||
//CLogger::Get ()->Write (FromRtkgpio, LogDebug, "Pin %d level high", nPin); | ||
return RtkGpioLevelHigh; | ||
break; | ||
} | ||
|
||
CLogger::Get ()->Write (FromRtkgpio, LogError, "Invalid level"); | ||
return RtkGpioLevelUnknown; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// | ||
// rtkgpio.h | ||
// | ||
// Circle - A C++ bare metal environment for Raspberry Pi | ||
// Copyright (C) 2020 H. Kocevar <[email protected]> | ||
// | ||
// This program 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. | ||
// | ||
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | ||
// | ||
#ifndef _gpio_rtkgpio_h | ||
#define _gpio_rtkgpio_h | ||
|
||
#include <circle/usb/usbserialch341.h> | ||
#include <circle/types.h> | ||
|
||
enum TRtkGpioDirection | ||
{ | ||
RtkGpioDirectionOutput, | ||
RtkGpioDirectionInput | ||
}; | ||
|
||
enum TRtkGpioLevel | ||
{ | ||
RtkGpioLevelUnknown, | ||
RtkGpioLevelLow, | ||
RtkGpioLevelHigh | ||
}; | ||
|
||
enum TRtkGpioPull | ||
{ | ||
RtkGpioPullNone, | ||
RtkGpioPullDown, | ||
RtkGpioPullUp | ||
}; | ||
|
||
class CRTKGpioDevice | ||
{ | ||
public: | ||
CRTKGpioDevice (CUSBSerialCH341Device *pCH341); | ||
~CRTKGpioDevice (); | ||
|
||
boolean Initialize (void); | ||
boolean GetVersion (void); | ||
|
||
boolean SetPinDirection (unsigned nPin, TRtkGpioDirection eDirection); | ||
boolean SetPinDirectionOutput (unsigned nPin); | ||
boolean SetPinDirectionInput (unsigned nPin); | ||
|
||
boolean SetPinPull (unsigned nPin, TRtkGpioPull ePull); | ||
boolean SetPinPullUp (unsigned nPin); | ||
boolean SetPinPullDown (unsigned nPin); | ||
boolean SetPinPullNone (unsigned nPin); | ||
|
||
boolean SetPinLevel (unsigned nPin, TRtkGpioLevel eLevel); | ||
boolean SetPinLevelLow (unsigned nPin); | ||
boolean SetPinLevelHigh (unsigned nPin); | ||
|
||
TRtkGpioLevel GetPinLevel (unsigned nPin); | ||
|
||
private: | ||
CUSBSerialCH341Device *m_pCH341; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,9 @@ | ||
README | ||
|
||
To use this sample program you need a RTK.GPIO board allowing you to increase the number of GPIO pins. | ||
RTK.GPIO board uses USB to serial IC Winchiphead CH341/CH340 to communicate to Raspberry Pi. | ||
RTK.GPIO board uses USB to serial IC Winchiphead CH340 to communicate to Raspberry Pi. | ||
The board must be connected to an USB port of the Raspberry Pi and ready when the Raspberry Pi is started. | ||
|
||
First blink 5 times to show the image was loaded right. | ||
After initializing the USB driver stack the sample program first toggles the level of a single GPIO output | ||
a couple of times (can be connected to a LED). | ||
Afterwards, another GPIO pin configured as input samples the level (can be connected to a button). | ||
After initializing the USB driver stack the sample program drives GPIO0 - GPIO7 outputs | ||
(can be connected to a LED), and polls the level of GPIO22 - GPIO25 inputs (can be connected to a button). |
Oops, something went wrong.