タッチセンサの感度調整ツール「CapsenseTuner」で、I2C通信を使う例はよく見ます。サンプルもI2C通信のみしかありません。でもUARTにも対応していて、CapsenseTunerでも接続先をUARTに設定することができます。サイトにも、できるよと情報があるのですが、実際のプログラムやプロジェクトの細かい設定までは、説明が見つかりません。
いろいろやってみたところ、うまく動いたのでメモしておきます。
#include "cy_pdl.h"
#include "cybsp.h"
#include "cycfg.h"
#include "cycfg_capsense.h"
#include "cy_gpio.h"
#define CAPSENSE_INTR_PRIORITY (3u) // psoc4 priority = 0~3
#define CY_ASSERT_FAILED (0u)
static void initialize_capsense_uart(void);
static void capsense_isr(void);
#define MAX_S 6
uint8_t led = 0;
uint8_t touch_status[MAX_S] = { 0 };
uint8_t touch[MAX_S] = { 0 };
cy_stc_scb_uart_context_t CYBSP_UART_context;
void TunerSend(void * context)
{
uint8_t uartTxHeader[] = {0x0Du, 0x0Au};
uint8_t uartTxTail[] = {0x00u, 0xFFu, 0xFFu};
(void)context;
Cy_SCB_UART_PutArrayBlocking(CYBSP_UART_HW, &(uartTxHeader[0u]), sizeof(uartTxHeader));
Cy_SCB_UART_PutArrayBlocking(CYBSP_UART_HW, (uint8_t *)&cy_capsense_tuner, sizeof(cy_capsense_tuner));
Cy_SCB_UART_PutArrayBlocking(CYBSP_UART_HW, uartTxTail, sizeof(uartTxTail));
}
void TunerReceive(uint8_t ** packet, uint8_t ** tunerPacket, void * context)
{
uint32_t i;
(void) context;
static uint32_t dataIndex = 0u;
static uint8_t commandPacket[16u] = {0u};
while(0u != Cy_SCB_UART_GetNumInRxFifo(CYBSP_UART_HW))
{
commandPacket[dataIndex++] = (uint8_t)Cy_SCB_UART_Get(CYBSP_UART_HW);
if (CY_CAPSENSE_COMMAND_PACKET_SIZE <= dataIndex)
{
if (CY_CAPSENSE_COMMAND_OK == Cy_CapSense_CheckTunerCmdIntegrity(&commandPacket[0u]))
{
/* Found a correct command, reset data index and assign pointers to buffers */
dataIndex = 0u;
*tunerPacket = (uint8_t *)&cy_capsense_tuner;
*packet = &commandPacket[0u];
break;
}
else
{
/* Command is not correct, remove the first byte in commandPacket FIFO */
dataIndex--;
for(i = 0u; i < (CY_CAPSENSE_COMMAND_PACKET_SIZE - 1u); i++)
{
commandPacket[i] = commandPacket[i + 1u];
}
}
}
}
}
int main(void) {
cy_rslt_t result;
// Initialize Device and Peripherals
result = cybsp_init();
if (result != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
// Enable Global Interrupts
__enable_irq();
// StartUp LED
for (int i = 0; i < 10; i++) {
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 1);
Cy_SysLib_Delay(25);
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 0);
Cy_SysLib_Delay(50);
}
// CAPSENSE & UART
initialize_capsense_uart();
// CAPSENSE First SCAN
Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
// Loop
for (;;) {
//
if (CY_CAPSENSE_NOT_BUSY == Cy_CapSense_IsBusy(&cy_capsense_context)) {
// CAPSENSE Process all widgets
Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
led = 0;
for (int i = 0; i < MAX_S; i++) {
if (0 != Cy_CapSense_IsWidgetActive(i, &cy_capsense_context)) {
if (touch_status[i] == 0) {
touch_status[i] = 1;
touch[i] = 1;
} else {
touch[i] = 0;
}
} else {
touch[i] = 0;
touch_status[i] = 0;
}
if (touch[i] == 1) {
led = 1;
}
}
if (led == 1) {
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 1);
} else {
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 0);
}
// CAPSENSE Tuner
Cy_CapSense_RunTuner(&cy_capsense_context);
// CAPSENSE Start the next scan
Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
}
}
}
// CAPSENSE
static void initialize_capsense_uart(void) {
//CAPSENSE
cy_capsense_status_t status = CY_CAPSENSE_STATUS_SUCCESS;
const cy_stc_sysint_t capsense_interrupt_config = {
.intrSrc = CYBSP_CSD_IRQ, .intrPriority = CAPSENSE_INTR_PRIORITY, };
status = Cy_CapSense_Init(&cy_capsense_context);
if (CY_CAPSENSE_STATUS_SUCCESS == status) {
Cy_SysInt_Init(&capsense_interrupt_config, capsense_isr);
NVIC_ClearPendingIRQ(capsense_interrupt_config.intrSrc);
NVIC_EnableIRQ(capsense_interrupt_config.intrSrc);
status = Cy_CapSense_Enable(&cy_capsense_context);
}
// UART
// Register communication CALLBACKS
cy_capsense_context.ptrInternalContext->ptrTunerSendCallback = TunerSend;
cy_capsense_context.ptrInternalContext->ptrTunerReceiveCallback = TunerReceive;
Cy_SCB_UART_Init(CYBSP_UART_HW, &CYBSP_UART_config, &CYBSP_UART_context);
Cy_SCB_UART_Enable(CYBSP_UART_HW);
}
static void capsense_isr(void) {
Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context);
}