3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

W6300-EVB-Pico で HTTP リクエスト時に割り込み処理を行う方法

Last updated at Posted at 2025-10-13

W6300-EVB-Pico 上で HTTPリクエストがあったタイミングで、ページ内容の更新やスリープからの復帰などの処理を行いたい場合があります。

この記事では、WIZnet チップのソケットイベント(接続/切断/受信/タイムアウト)を割り込みで検知する方法 をまとめます。

割り込みマスクの設定

まずは、どのイベントで割り込みを発生させるかのフラグを設定します。
各ソケットごとに以下の割り込みフラグが用意されています。

フラグ 説明
SIK_CONNECTED 接続確立時
SIK_DISCONNECTED 切断時
SIK_RECEIVED データ受信時
SIK_TIMEOUT タイムアウト時

SIK_SENT も定義されていますが、このフラグを有効にすると動作が不安定になりました。

これらのフラグは、ctlsocket() 関数で設定します。

ctlsocket(ソケット番号, CS_SET_INTMASK, &マスク);

たとえば、ソケット0で上記すべてのイベントを有効にする場合は以下のようにします。

sockint_kind mask = (SIK_CONNECTED | SIK_DISCONNECTED | SIK_RECEIVED | SIK_TIMEOUT);
ctlsocket(0, CS_SET_INTMASK, &mask);

複数ソケットを同時に設定したい場合は、ループで一括設定が可能です。

for (uint8_t sock = 0; sock < HTTP_SOCKET_MAX_NUM; sock++) {
    ctlsocket(sock, CS_SET_INTMASK, &mask);
}

WIZnet チップ全体の割り込みを有効化

続いて、チップ本体のソケット割り込みを有効にします。
有効化すると、ソケットでイベントが発生した際に INT ピン が Low になります。

ctlwizchip(CW_SET_INTRMASK, &ソケットマスク);

ソケットマスク には、割り込みを有効にしたいソケット番号をビットで指定します。
例えば、ソケット0〜3をすべて有効にする場合は以下の通りです。

uint32_t chip_intr = 0;
for (uint8_t sock = 0; sock < HTTP_SOCKET_MAX_NUM; sock++) {
    chip_intr |= (1 << sock) << 8;  // ソケットごとにビットをセット
}
ctlwizchip(CW_SET_INTRMASK, &chip_intr);

GPIO割り込みハンドラの登録

次に、RP2040 側で GPIO 割り込みを設定し、コールバック関数を登録します。

gpio_set_irq_enabled_with_callback(PIN_INT, GPIO_IRQ_EDGE_FALL, true, &interrupt_callback);

PIN_INT は、wizchip_spi.h の中であらかじめ定義されています。W6300-EVB-Pico の場合、GPIO15 に INT ピンが接続されています。

割り込みコールバック関数の実装

実際にどのソケットで何が起きたかは、ctlsocket()CS_GET_INTERRUPT を使って取得できます。

void interrupt_callback(uint gpio, uint32_t events) {
    uint8_t sock;
    sockint_kind sock_intr;

    for (sock = 0; sock < HTTP_SOCKET_MAX_NUM; sock++) {
        if (ctlsocket(sock, CS_GET_INTERRUPT, &sock_intr) == SOCK_OK) {
            if (sock_intr & SIK_CONNECTED) {
                printf("Socket %d: CONNECTED\n", sock);
                // ここでページ更新やスリープ解除などを実行
            }
            if (sock_intr & SIK_DISCONNECTED) {
                printf("Socket %d: DISCONNECTED\n", sock);
            }
            if (sock_intr & SIK_RECEIVED) {
                printf("Socket %d: RECEIVED\n", sock);
            }
            if (sock_intr & SIK_TIMEOUT) {
                printf("Socket %d: TIMEOUT\n", sock);
            }
            // フラグをクリア
            ctlsocket(sock, CS_CLR_INTERRUPT, &sock_intr);
        }
    }
}

全体のコード

以下に、HTTP サーバーと割り込み処理を組み合わせた全体のコード例を示します。

/**
    Copyright (c) 2021 WIZnet Co.,Ltd
    SPDX-License-Identifier: BSD-3-Clause
 
    Modified by namo02268, 2025
 */

#include <stdio.h>

#include "pico/stdlib.h"
#include "hardware/gpio.h"

#include "port_common.h"

#include "wizchip_conf.h"
#include "wizchip_spi.h"

#include "socket.h"
#include "httpServer.h"

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)

#define HTTP_SOCKET_MAX_NUM 4

#define index_page  "<!DOCTYPE html>"\
                    "<html lang=\"en\">"\
                    "<head>"\
                        "<meta charset=\"UTF-8\">"\
                        "<title>Interrupt Test</title>"\
                    "</head>"\
                    "<body>"\
                        "<h1>Hello, World!</h1>"\
                    "</body>"\
                    "</html>"

static wiz_NetInfo g_net_info = {
    .mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address
    .ip = {192, 168, 0, 30},                     // IP address
    .sn = {255, 255, 255, 0},                    // Subnet Mask
    .gw = {192, 168, 0, 1},                     // Gateway
    .dns = {8, 8, 8, 8},                         // DNS server
    .dhcp = NETINFO_STATIC
};

static uint8_t g_http_send_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};
static uint8_t g_http_recv_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};
static uint8_t g_http_socket_num_list[HTTP_SOCKET_MAX_NUM] = {0, 1, 2, 3};

// 割り込みコールバック関数
void interrupt_callback(uint gpio, uint32_t events) {
    uint8_t sock;
    sockint_kind sock_intr;

    for (sock = 0; sock < HTTP_SOCKET_MAX_NUM; sock++) {
        if (ctlsocket(sock, CS_GET_INTERRUPT, &sock_intr) == SOCK_OK) {
            if (sock_intr & SIK_CONNECTED) {
                printf("Socket %d: CONNECTED\n", sock);
                // ここでページ更新やスリープ解除などを実行
            }
            if (sock_intr & SIK_DISCONNECTED) {
                printf("Socket %d: DISCONNECTED\n", sock);
            }
            if (sock_intr & SIK_RECEIVED) {
                printf("Socket %d: RECEIVED\n", sock);
            }
            if (sock_intr & SIK_TIMEOUT) {
                printf("Socket %d: TIMEOUT\n", sock);
            }
            // フラグをクリア
            ctlsocket(sock, CS_CLR_INTERRUPT, &sock_intr);
        }
    }
}

int main() {
    stdio_init_all();
    sleep_ms(3000);

    wizchip_spi_initialize();
    wizchip_cris_initialize();
    wizchip_reset();
    wizchip_initialize();
    wizchip_check();

    network_initialize(g_net_info);
    httpServer_init(g_http_send_buf, g_http_recv_buf, HTTP_SOCKET_MAX_NUM, g_http_socket_num_list);
    print_network_information(g_net_info);
    reg_httpServer_webContent("index.html", index_page);

    // ソケット割り込みマスク設定
    uint8_t sock = 0;
    sockint_kind mask = (SIK_CONNECTED | SIK_DISCONNECTED | SIK_RECEIVED | SIK_TIMEOUT);
    for(sock=0; sock<HTTP_SOCKET_MAX_NUM; sock++) {
        ctlsocket(sock, CS_SET_INTMASK, &mask);
    }

    // チップ全体の割り込みマスク設定
    uint32_t chip_intr = 0;
    for(sock = 0; sock < HTTP_SOCKET_MAX_NUM; sock++) {
      chip_intr |= ((1 << sock) << 8);
    }
    ctlwizchip(CW_SET_INTRMASK, &chip_intr);

    // GPIO 割り込み登録
    gpio_set_irq_enabled_with_callback(PIN_INT, GPIO_IRQ_EDGE_FALL, true, &interrupt_callback);

    while (1) {
        for (uint8_t i = 0; i < HTTP_SOCKET_MAX_NUM; i++) {
            httpServer_run(i);
        }
    }
}

使用しているコードは、WIZnet社が公開しているBSD 3-Clauseライセンスのサンプルコードをもとに改変しています。オリジナルのソースコードは WIZnet GitHub Repository で公開されています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?