많은 개발하시는 분들은 애쉴론의 전력선 통신 칩이나 FT칩을 이용할때 단독으로 칩을 사용하기도 하지만 많은 경우 별도의 호스트 프로세서와 같이 사용을 합니다. 이때 대부분 시리얼 통신을 선호하지요. 그래서 어떻게 뉴론C를 이용해서 시리얼 프로그래밍을 할지 고민합니다.
이전 FT3120/3150의 경우 칩 내부에 드라이버가 포함되어 있지 않기 때문에 핸들링하기가 쉽지 않았지만 PL31xx부터는 내부 드라이버를 이용해서 좀더 쉽게 사용할 수 있게 되어 있습니다. 물론 최신 칩들보다는 사실 조금... 부족합니다. ㅎㅎ
일반적인 상식?으로 제공되는 API를 이용하여 프로그래밍을 하면 패킷을 받을때 패킷을 잃어버리는 경우가 생기곤 합니다. 이를 피하기 위해 두개의 버퍼를 사용해서 프로그래밍 합니다.
아래 소스코드를 참고하기 바랍니다. 아래 소스는 PL3120/3150을 사용할 때 쓰입니다.
기본적으로 specify_io_clock "10 MHz"을 선언해줘야 합니다.
// pragmas #pragma num_alias_table_entries 0 #pragma specify_io_clock "10 MHz" // SCI_4800 etc., are declared in this header file #include <io_types.h> // SCI declaration IO_8 sci baud(SCI_4800) iosci; // Buffers and variable declarations char szRxBufA[50]; char szRxBufB[50]; unsigned short rx_count; int bufTog; // Function declaration void processRxData(char buffer[50], unsigned short rx_count); when(io_in_ready(iosci)) { // Switch to the other buffer and keep the RX count rx_count = io_in_request(iosci, (bufTog) ? szRxBufA : szRxBufB, sizeof(szRxBufA)); bufTog ^= 1; // toggle this // Do something with RX data using the filled data buffer. // It may be only a few bytes, or it may be close to 50 bytes. processRxData((bufTog) ? szRxBufA : szRxBufB, rx_count); } when (reset) { (void)io_in_request(iosci, szRxBufA, 50); bufTog = 0; // indicates that A is in use. } void processRxData(char buffer[50], unsigned short rx_count) { io_out_request(iosci, buffer, rx_count); }
io_in_ready는 시리얼 핀을 통해 데이터가 들어오는 순간 when절이 시행됩니다. 만약 두개의 버퍼를 사용하지 않을경우 한 패킷에서 첫번째 바이트만 처리하는 결과를 초래하게 됩니다. 왜 조금 부족하다고 얘기한 이유이기도 합니다. 만약 15바이트를 받게 되면 처음 1바이트를 처리하고 다음 when절이 실행될때 나머지 14바이트를 받게 됩니다. 사실 완벽하지 않은 함수인거죠.
혹은 고정된 데이터길이를 사용할 경우는 굳이 두개의 버퍼를 사용하지 않아도 됩니다.
예를 들어 when (io_in_ready(iosci) == 데이터길이) 이렇게 하면 설정한 데이터 길이만큼 받아야만 이 when절이 실행됩니다. 하지만 만약 설정한 데이터 길이보다 작은 데이터가 들어오거나 더 큰 데이터가 들어오게 되면 그 다음부터 문제가 발생할 수 있기도 합니다. 물론 온보드에서 호스트프로세서에서 잘못 프로그래밍이 되지 않는 이상 길이가 변경될 확률은 작겠지만 그래도 프로그래머 입장에서는 이를 고려하지 않을 수는 없을겁니다.
보내는 건 간단합니다. 그냥 io_out_request를 이용하면 됩니다. 굳이 소스내에서 핸들링 해줄 필요가 없죠.
중요한것 중에 하나가 reset()에서 io_in_request를 이용해 한번 초기화를 해줘야 합니다.
간단한 예제파일을 여기서 다운받을 수 있습니다.
그리고 다음은 FT5000을 사용할때의 예제입니다. 대부분이 PL칩의 소스와 동일합니다. 단 받을 함수가 다릅니다. 그리고 최신 업데이트가 패치되었는지 확인해야 합니다.
먼저 5000시리즈를 위해 최신 업데이트를 다운받아 설명에 따라 업데이트 합니다.
// pragmas
#pragma num_alias_table_entries 0
#pragma specify_io_clock "10 MHz"
// SCI_4800 etc., are declared in this header file
#include <io_types.h>
// SCI declaration
IO_8 sci baud(SCI_115200) iosci;
// Buffers and variable declarations
char szRxBufA[50];
char szRxBufB[50];
unsigned short rx_count;
int bufTog;
// Function declaration
void processRxData(char buffer[50], unsigned short rx_count);
when(io_in_ready(iosci))
{
// Switch to the other buffer and keep the RX count
rx_count = sci_in_request_ex((bufTog) ? szRxBufA : szRxBufB, sizeof(szRxBufA));
bufTog ^= 1; // toggle this
// Do something with RX data using the filled data buffer.
// It may be only a few bytes, or it may be close to 50 bytes.
processRxData((bufTog) ? szRxBufA : szRxBufB, rx_count);
}
when (reset)
{
(void)io_in_request(iosci, szRxBufA, 50);
bufTog = 0; // indicates that A is in use.
}
void processRxData(char buffer[50], unsigned short rx_count)
{
io_out_request(iosci, buffer, rx_count);
}
그럼 여기까지 시리얼 통신을 이용해 애쉴론의 5000시리즈 칩과 PL칩을 이용해 시리얼 통신을 하는 Neuron C 프로그래밍 예였습니다.
'Network Tech > 소프트웨어' 카테고리의 다른 글
애쉴론 LonScanner 소프트웨어 라이센스 신청방법 (0) | 2016.05.11 |
---|---|
굳나잇! Cortana / SmartServer (0) | 2016.02.19 |
스마트서버와 통신하는 아이폰 앱 [soap call in Xcode] (0) | 2014.08.04 |
애쉴론 소프트웨어 운영체제 지원 리스트 (0) | 2014.05.09 |
PL칩 패리티비트 사용방법 - 시리얼 통신 (0) | 2014.04.02 |