Skip to content

Commit

Permalink
[#83] UART RX fixed; UARTTX::puts does not work in COG mode
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidZemon committed Apr 6, 2016
1 parent 67d5267 commit 2c4e967
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 67 deletions.
4 changes: 2 additions & 2 deletions Examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ add_subdirectory(GettingStarted)
add_subdirectory(Hello)
add_subdirectory(Libpropeller_Pwm32)
add_subdirectory(PropWare_Blinky)
add_subdirectory(PropWare_DuplexUART)
add_subdirectory(PropWare_Eeprom)
add_subdirectory(PropWare_FileReader)
add_subdirectory(PropWare_FileWriter)
Expand All @@ -20,13 +19,14 @@ add_subdirectory(PropWare_Ping)
add_subdirectory(PropWare_Queue)
add_subdirectory(PropWare_Runnable)
add_subdirectory(PropWare_Scanner)
add_subdirectory(PropWare_SimplexUART)
add_subdirectory(PropWare_Simple_Hybrid)
add_subdirectory(PropWare_SPI)
add_subdirectory(PropWare_Spin2Dat)
add_subdirectory(PropWare_Stepper)
add_subdirectory(PropWare_StringBuilder)
add_subdirectory(PropWare_SynchronousPrinter)
add_subdirectory(PropWare_UARTRX)
add_subdirectory(PropWare_UARTTX)
add_subdirectory(PropWare_Utility)
add_subdirectory(PropWare_WatchDog)
add_subdirectory(PropWare_WS2812)
Expand Down
6 changes: 0 additions & 6 deletions Examples/PropWare_DuplexUART/CMakeLists.txt

This file was deleted.

7 changes: 3 additions & 4 deletions Examples/PropWare_Scanner/Scanner_Demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ int main () {
char name[64];
unsigned int age;

pwOut.printf("Hello! I'd like to teach you how to use PropWare to read from the terminal!\n");
pwOut << "Hello! I'd like to teach you how to use PropWare to read from the terminal!\n";

do {
pwOut << "First, what's your name?\n>>> ";
pwIn.gets(userInput, sizeof(userInput));
strcpy(name, userInput);
pwIn >> name;

pwOut << "And how old are you?\n>>> ";
pwIn >> age;
Expand All @@ -63,7 +62,7 @@ int main () {
YES_NO_COMP);
} while (isAnswerNo(userInput));

pwOut.printf("Hello, %s!\n", name);
pwOut << "Hello, " << name << "!\n";
return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions Examples/PropWare_UARTRX/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.3)
find_package(PropWare REQUIRED)

project(UARTRX_Demo)

create_simple_executable(${PROJECT_NAME} UARTRX_Demo.cpp)
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @file DuplexUART_Demo.cpp
* @file UARTTX_Demo.cpp
*
* @author David Zemon
*
Expand Down Expand Up @@ -36,30 +36,53 @@ const PropWare::Port::Mask TX_PIN = PropWare::Port::P12;
const PropWare::Port::Mask RX_PIN = PropWare::Port::P13;
const PropWare::UART::Parity PARITY = PropWare::UART::NO_PARITY;

void error (const PropWare::ErrorCode err);

class Listener : public PropWare::Runnable {
public:
template<size_t N>
Listener (const uint32_t (&stack)[N])
: Runnable(stack) {
}

void run ();
void run () {
PropWare::ErrorCode err;
int32_t receivedLength;

this->init();
pwSyncOut.printf("Ready to receive!\n");

while (1) {
receivedLength = sizeof(this->m_buffer);
if ((err = this->m_listener.fgets(this->m_buffer, &receivedLength)))
error(err);

pwSyncOut.printf("Data (%d chars): \"%s\"\n", receivedLength, this->m_buffer);
}
}

void init () {
this->m_listener.set_rx_mask(RX_PIN);
this->m_listener.set_baud_rate(BAUD_RATE);
this->m_listener.set_parity(PARITY);
//memset(m_buffer, 0, sizeof(m_buffer));

void init ();
// A very short wait to ensure the main cog has finished printing its "I'm ready" statement before we start
// printing ours
waitcnt(20 * MILLISECOND + CNT);
}

private:
PropWare::UARTRX m_listener;
char m_buffer[sizeof(TEST_STRING)];
};

void error (const PropWare::ErrorCode err);

/**
* @example DuplexUART_Demo.cpp
*
* Write "Hello world!" out via UART protocol and receive an echo
*
* @include PropWare_DuplexUART/CMakeLists.txt
* @include PropWare_UARTRX/CMakeLists.txt
*/
int main () {
uint32_t threadStack[256];
Expand Down Expand Up @@ -89,30 +112,3 @@ void error (const PropWare::ErrorCode err) {
waitcnt(100 * MILLISECOND);
}
}

void Listener::run () {
PropWare::ErrorCode err;
int32_t receivedLength;

this->init();
pwSyncOut.printf("Ready to receive!\n");

while (1) {
receivedLength = sizeof(this->m_buffer);
if ((err = this->m_listener.fgets(this->m_buffer, &receivedLength)))
error(err);

pwSyncOut.printf("Data (%d chars): \"%s\"\n", receivedLength, this->m_buffer);
}
}

void Listener::init () {
this->m_listener.set_rx_mask(RX_PIN);
this->m_listener.set_baud_rate(BAUD_RATE);
this->m_listener.set_parity(PARITY);
memset(m_buffer, 0, sizeof(m_buffer));

// A very short wait to ensure the main cog has finished printing its "I'm ready" statement before we start
// printing ours
waitcnt(10 * MILLISECOND + CNT);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ find_package(PropWare REQUIRED)

project(SimplexUART_Demo C CXX ASM)

create_simple_executable(${PROJECT_NAME} SimplexUART_Demo.cpp)
create_simple_executable(${PROJECT_NAME} UARTTX_Demo.cpp)
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @file SimplexUART_Demo.cpp
* @file UARTTX_Demo.cpp
*
* @author David Zemon
*
Expand Down Expand Up @@ -38,7 +38,7 @@ const int32_t DELAY = 200;
*
* Write "Hello world!" out via UART protocol
*
* @include PropWare_SimplexUART/CMakeLists.txt
* @include PropWare_UARTTX/CMakeLists.txt
*/
int main () {
PropWare::ErrorCode err;
Expand Down
5 changes: 5 additions & 0 deletions PropWare/hmi/input/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ class Scanner {
}
}

template<size_t N>
const ErrorCode get (char (&buffer)[N]) {
return this->gets(buffer, N);
}

/**
* @overload
*/
Expand Down
4 changes: 2 additions & 2 deletions PropWare/serial/uart/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class UART {
static const int *PARALLAX_STANDARD_RX;

public:
ErrorCode set_data_width (const uint8_t dataWidth) {
virtual ErrorCode set_data_width (const uint8_t dataWidth) {
if (1 > dataWidth || dataWidth > 16)
return UART::INVALID_DATA_WIDTH;

Expand All @@ -137,7 +137,7 @@ class UART {
return this->m_dataWidth;
}

void set_parity (const UART::Parity parity) {
virtual void set_parity (const UART::Parity parity) {
this->m_parity = parity;
this->set_parity_mask();
this->set_stop_bit_mask();
Expand Down
58 changes: 41 additions & 17 deletions PropWare/serial/uart/uartrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ class UARTRX : public UART,
/**
* @see PropWare::SimplexUART::AbstractSimplexUART()
*/
UARTRX () : UART() {
UARTRX () {
// Can't rely on parent constructor because the setters are virtual
this->set_data_width(UART::DEFAULT_DATA_WIDTH);
this->set_parity(UART::DEFAULT_PARITY);
this->set_stop_bit_width(UART::DEFAULT_STOP_BIT_WIDTH);
this->set_baud_rate(*UART::DEFAULT_BAUD);
this->set_rx_mask((Port::Mask) (1 << *UART::PARALLAX_STANDARD_RX));
}

Expand All @@ -54,9 +59,12 @@ class UARTRX : public UART,
* @param[in] tx Pin mask for TX (transmit) pin
* @param[in] rx Pin mask for RX (receive) pin
*/
UARTRX (const Port::Mask rx) : UART() {
// Set rx direction second so that, in the case of half-duplex, the
// pin floats high
UARTRX (const Port::Mask rx) {
// Can't rely on parent constructor because the setters are virtual
this->set_data_width(UART::DEFAULT_DATA_WIDTH);
this->set_parity(UART::DEFAULT_PARITY);
this->set_stop_bit_width(UART::DEFAULT_STOP_BIT_WIDTH);
this->set_baud_rate(*UART::DEFAULT_BAUD);
this->set_rx_mask(rx);
}

Expand All @@ -70,6 +78,22 @@ class UARTRX : public UART,
return this->m_pin.get_mask();
}

virtual ErrorCode set_data_width (const uint8_t dataWidth) {
ErrorCode err;
check_errors(UART::set_data_width(dataWidth));

this->set_msb_mask();
this->set_receivable_bits();

return NO_ERROR;
}

virtual void set_parity (const UART::Parity parity) {
UART::set_parity(parity);
this->set_msb_mask();
this->set_receivable_bits();
}

uint32_t receive () const {
uint32_t rxVal;
uint32_t wideDataMask = this->m_dataMask;
Expand Down Expand Up @@ -209,7 +233,7 @@ class UARTRX : public UART,

#ifndef DOXYGEN_IGNORE
__asm__ volatile (
FC_START("ShiftInDataStart", "ShiftInDataEnd")
FC_START("ShiftInDataStart%=", "ShiftInDataEnd%=")
" shr %[_waitCycles], #1 \n\t"
" add %[_waitCycles], %[_bitCycles] \n\t"
" waitpne %[_rxMask], %[_rxMask] \n\t"
Expand All @@ -221,11 +245,11 @@ class UARTRX : public UART,
" shr %[_data],# 1 \n\t"
" test %[_rxMask],ina wz \n\t"
" muxnz %[_data], %[_msbMask] \n\t"
" djnz %[_bits], #" FC_ADDR("loop%=", "ShiftInDataStart") " \n\t"
" djnz %[_bits], #" FC_ADDR("loop%=", "ShiftInDataStart%=") " \n\t"

// Wait for a stop bit
" waitpeq %[_rxMask], %[_rxMask] \n\t"
FC_END("ShiftInDataEnd")
FC_END("ShiftInDataEnd%=")
:// Outputs
[_data] "+r"(data),
[_waitCycles] "+r"(waitCycles),
Expand Down Expand Up @@ -256,7 +280,7 @@ class UARTRX : public UART,
#ifndef DOXYGEN_IGNORE
// Initialize variables
__asm__ volatile (
FC_START("ShiftInStringStart", "ShiftInStringEnd")
FC_START("ShiftInStringStart%=", "ShiftInStringEnd%=")
"outerLoop%=: \n\t"
// Initialize the index variable
" mov %[_bitIdx], %[_bits] \n\t"
Expand All @@ -273,7 +297,7 @@ class UARTRX : public UART,
" shr %[_data], #1 \n\t"
" test %[_rxMask], ina wz \n\t"
" muxnz %[_data], %[_msbMask] \n\t"
" djnz %[_bitIdx], #" FC_ADDR("innerLoop%=", "ShiftInStringStart") " \n\t"
" djnz %[_bitIdx], #" FC_ADDR("innerLoop%=", "ShiftInStringStart%=") " \n\t"

// Write the word back to the buffer in HUB memory
" wrbyte %[_data], %[_bufAdr] \n\t"
Expand All @@ -296,8 +320,8 @@ class UARTRX : public UART,

// Finally, loop to the beginning if the delimiter is not equal to our most recent word and
// the buffer is not about to overflow
"if_nz_and_c jmp #" FC_ADDR("outerLoop%=", "ShiftInStringStart") " \n\t"
FC_END("ShiftInStringEnd")
"if_nz_and_c jmp #" FC_ADDR("outerLoop%=", "ShiftInStringStart%=") " \n\t"
FC_END("ShiftInStringEnd%=")
:// Outputs
[_bitIdx] "+r"(bitIdx),
[_waitCycles] "+r"(waitCycles),
Expand Down Expand Up @@ -329,9 +353,9 @@ class UARTRX : public UART,
#ifndef DOXYGEN_IGNORE
// Initialize variables
__asm__ volatile (
#define ASMVAR(name) FC_ADDR(#name "%=", "ShiftInArrayDataStart")
FC_START("ShiftInArrayDataStart", "ShiftInArrayDataEnd")
" jmp #" FC_ADDR("outerLoop%=", "ShiftInArrayDataStart") " \n\t"
#define ASMVAR(name) FC_ADDR(#name "%=", "ShiftInArrayDataStart%=")
FC_START("ShiftInArrayDataStart%=", "ShiftInArrayDataEnd%=")
" jmp #" FC_ADDR("outerLoop%=", "ShiftInArrayDataStart%=") " \n\t"

// Temporary variables
"bitIdx%=: \n\t"
Expand All @@ -358,7 +382,7 @@ class UARTRX : public UART,
" shr " ASMVAR(data) ", #1 \n\t"
" test %[_rxMask], ina wz \n\t"
" muxnz " ASMVAR(data) ", %[_msbMask] \n\t"
" djnz " ASMVAR(bitIdx) ", #" FC_ADDR("innerLoop%=", "ShiftInArrayDataStart") " \n\t"
" djnz " ASMVAR(bitIdx) ", #" FC_ADDR("innerLoop%=", "ShiftInArrayDataStart%=") " \n\t"

// Write the word back to the buffer in HUB memory
" wrbyte " ASMVAR(data) ", %[_bufAdr] \n\t"
Expand All @@ -370,8 +394,8 @@ class UARTRX : public UART,

// Wait for the stop bits and the loop back
" waitpeq %[_rxMask], %[_rxMask] \n\t"
" djnz %[_length], #" FC_ADDR("outerLoop%=", "ShiftInArrayDataStart") " \n\t"
FC_END("ShiftInArrayDataEnd")
" djnz %[_length], #" FC_ADDR("outerLoop%=", "ShiftInArrayDataStart%=") " \n\t"
FC_END("ShiftInArrayDataEnd%=")
#undef ASMVAR
:// Outputs
[_bufAdr] "+r"(buffer),
Expand Down

0 comments on commit 2c4e967

Please sign in to comment.