mirror of
https://github.com/whowechina/aic_pico.git
synced 2024-11-24 14:00:09 +01:00
PN5180 work started (only reads a bit Mifare)
This commit is contained in:
parent
4951c67feb
commit
4d175076d5
@ -5,7 +5,7 @@ function(make_firmware board board_def)
|
||||
pico_sdk_init()
|
||||
add_executable(${board}
|
||||
main.c save.c config.c commands.c light.c keypad.c
|
||||
aime.c cli.c pn532.c
|
||||
aime.c cli.c pn532.c pn5180.c
|
||||
usb_descriptors.c)
|
||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||
pico_enable_stdio_usb(${board} 1)
|
||||
@ -21,7 +21,7 @@ function(make_firmware board board_def)
|
||||
|
||||
target_link_libraries(${board} PRIVATE
|
||||
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
|
||||
hardware_adc hardware_i2c hardware_watchdog
|
||||
hardware_adc hardware_i2c hardware_spi hardware_watchdog
|
||||
tinyusb_device tinyusb_board)
|
||||
|
||||
pico_add_extra_outputs(${board})
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "cli.h"
|
||||
|
||||
#include "pn532.h"
|
||||
#include "pn5180.h"
|
||||
|
||||
static int fps[2];
|
||||
void fps_count(int core)
|
||||
@ -146,6 +147,134 @@ static void handle_level(int argc, char *argv[])
|
||||
handle_display();
|
||||
}
|
||||
|
||||
static void handle_pnboot()
|
||||
{
|
||||
pn5180_reset();
|
||||
}
|
||||
|
||||
static void handle_pnver()
|
||||
{
|
||||
uint8_t buf[6];
|
||||
pn5180_read_eeprom(0x10, buf, sizeof(buf));
|
||||
|
||||
printf("Version: %02x %02x %02x %02x %02x %02x\n",
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
|
||||
pn5180_print_rf_cfg();
|
||||
}
|
||||
|
||||
static void handle_pnread(int argc, char *argv[])
|
||||
{
|
||||
int reg = cli_extract_non_neg_int(argv[0], 0);
|
||||
printf("%2d: %08lx\n", reg, pn5180_read_reg(reg));
|
||||
}
|
||||
|
||||
static void handle_pnmifare()
|
||||
{
|
||||
pn5180_load_rf_config(0x00, 0x80); // 1
|
||||
pn5180_rf_on(); // 2
|
||||
|
||||
sleep_ms(2000);
|
||||
|
||||
pn5180_and_reg(PN5180_REG_CRC_TX_CONFIG, 0xfffffffe); // 3
|
||||
pn5180_and_reg(PN5180_REG_CRC_RX_CONFIG, 0xfffffffe); // 4
|
||||
|
||||
pn5180_and_reg(PN5180_REG_IRQ_CLEAR, 0x000fffff); // 5
|
||||
pn5180_and_reg(PN5180_REG_SYSTEM_CONFIG, 0xfffffff8); // 6
|
||||
pn5180_or_reg(PN5180_REG_SYSTEM_CONFIG, 0x03); // 7
|
||||
|
||||
uint8_t buf[] = {0x26};
|
||||
pn5180_send_data(buf, sizeof(buf), 7); // 8
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
printf("irq: %08lx rx: %08lx\n", pn5180_read_reg(PN5180_REG_IRQ_STATUS),
|
||||
pn5180_read_reg(PN5180_REG_RX_STATUS));
|
||||
sleep_ms(2);
|
||||
}
|
||||
|
||||
uint8_t out[128] = {0};
|
||||
pn5180_read_data(out, 2); // 10
|
||||
|
||||
printf("2: %02x %02x\n", out[0], out[1]);
|
||||
|
||||
#if 0
|
||||
uint8_t anti_collision[] = {0x93, 0x20};
|
||||
pn5180_send_data(anti_collision, sizeof(anti_collision), 0);
|
||||
|
||||
pn5180_read_data(out + 2, 5);
|
||||
printf("5: %02x %02x %02x %02x %02x\n", out[2], out[3], out[4], out[5], out[6]);
|
||||
|
||||
pn5180_or_reg(PN5180_REG_CRC_RX_CONFIG, 0x01);
|
||||
pn5180_or_reg(PN5180_REG_CRC_TX_CONFIG, 0x01);
|
||||
|
||||
anti_collision[1] = 0x70;
|
||||
pn5180_send_data(anti_collision, sizeof(anti_collision), 0);
|
||||
pn5180_read_data(out + 7, 1); // sak
|
||||
printf("1: %02x\n", out[7]);
|
||||
#endif
|
||||
pn5180_rf_off();
|
||||
}
|
||||
|
||||
static void handle_pnfeli()
|
||||
{
|
||||
pn5180_load_rf_config(0x09, 0x89);
|
||||
pn5180_rf_on();
|
||||
|
||||
sleep_ms(1000);
|
||||
|
||||
pn5180_and_reg(PN5180_REG_SYSTEM_CONFIG, 0xffffffbf);
|
||||
|
||||
uint8_t cmd[] = {0x06, 0x00, 0xff, 0xff, 0x01, 0x00};
|
||||
|
||||
pn5180_send_data(cmd, 6, 0x00);
|
||||
|
||||
sleep_ms(100);
|
||||
|
||||
uint8_t out[32] = {0};
|
||||
pn5180_read_data(out, 20);
|
||||
|
||||
pn5180_rf_off();
|
||||
|
||||
printf("feli:");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
printf(" %02x", out[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void handle_pninv()
|
||||
{
|
||||
pn5180_load_rf_config(0x0d, 0x8d);
|
||||
pn5180_rf_on();
|
||||
|
||||
sleep_ms(1000);
|
||||
|
||||
pn5180_and_reg(PN5180_REG_IRQ_CLEAR, 0x000fffff); // 5
|
||||
pn5180_and_reg(PN5180_REG_SYSTEM_CONFIG, 0xfffffff8); // 6
|
||||
pn5180_or_reg(PN5180_REG_SYSTEM_CONFIG, 0x03); // 7
|
||||
|
||||
uint8_t cmd[] = {0x06, 0x01, 0x00};
|
||||
pn5180_send_data(cmd, 3, 0);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
printf("irq: %08lx rx: %08lx\n", pn5180_read_reg(PN5180_REG_IRQ_STATUS),
|
||||
pn5180_read_reg(PN5180_REG_RX_STATUS));
|
||||
sleep_ms(2);
|
||||
}
|
||||
|
||||
uint32_t rxstatus = pn5180_read_reg(PN5180_REG_RX_STATUS);
|
||||
int len = rxstatus & 0x1ff;
|
||||
uint8_t buf[len];
|
||||
pn5180_read_data(buf, len);
|
||||
|
||||
printf("uid:");
|
||||
for (int i = 0; i < len; i++) {
|
||||
printf(" %02x", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
pn5180_rf_off();
|
||||
}
|
||||
|
||||
void commands_init()
|
||||
{
|
||||
cli_register("display", handle_display, "Display all settings.");
|
||||
@ -154,4 +283,10 @@ void commands_init()
|
||||
cli_register("nfc", handle_nfc, "NFC debug.");
|
||||
cli_register("light", handle_light, "Turn on/off lights.");
|
||||
cli_register("level", handle_level, "Set light level.");
|
||||
cli_register("pnboot", handle_pnboot, "PN5180 reboot");
|
||||
cli_register("pnver", handle_pnver, "PN5180 version");
|
||||
cli_register("pnread", handle_pnread, "PN5180 debug rf");
|
||||
cli_register("pnmifare", handle_pnmifare, "PN5180 mifare");
|
||||
cli_register("pnfeli", handle_pnfeli, "PN5180 felica");
|
||||
cli_register("pninv", handle_pninv, "PN5180 15693");
|
||||
}
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "keypad.h"
|
||||
|
||||
#include "pn532.h"
|
||||
#include "pn5180.h"
|
||||
|
||||
#include "aime.h"
|
||||
|
||||
static struct {
|
||||
@ -211,6 +213,11 @@ void init()
|
||||
|
||||
pn532_init(I2C_PORT, I2C_SCL, I2C_SDA, I2C_FREQ);
|
||||
pn532_set_wait_loop(wait_loop);
|
||||
|
||||
pn5180_init(spi0, 16, 18, 19, 27, 17, 26);
|
||||
pn5180_load_rf_config(0x0d, 0x8d);
|
||||
pn5180_rf_on();
|
||||
|
||||
aime_init(cdc_aime_putc);
|
||||
|
||||
cli_init("aic_pico>", "\n << AIC Pico >>\n"
|
||||
|
208
firmware/src/pn5180.c
Normal file
208
firmware/src/pn5180.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* PN5180 NFC Reader
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/spi.h"
|
||||
|
||||
#include "pn5180.h"
|
||||
|
||||
#define IO_TIMEOUT_US 1000
|
||||
#define PN5180_I2C_ADDRESS 0x24
|
||||
|
||||
#define CMD_WRITE_REG 0x00
|
||||
#define CMD_WRITE_REG_OR 0x01
|
||||
#define CMD_WRITE_REG_AND 0x02
|
||||
#define CMD_READ_REG 0x04
|
||||
#define CMD_WRITE_EEPROM 0x06
|
||||
#define CMD_READ_EEPROM 0x07
|
||||
#define CMD_SEND_DATA 0x09
|
||||
#define CMD_READ_DATA 0x0a
|
||||
#define CMD_LOAD_RF_CONFIG 0x11
|
||||
#define CMD_RF_ON 0x16
|
||||
#define CMD_RF_OFF 0x17
|
||||
|
||||
static struct {
|
||||
spi_inst_t *port;
|
||||
uint8_t rst;
|
||||
uint8_t nss;
|
||||
uint8_t busy;
|
||||
} spi;
|
||||
|
||||
void pn5180_init(spi_inst_t *port, uint8_t rx, uint8_t sck, uint8_t tx,
|
||||
uint8_t rst, uint8_t nss, uint8_t busy)
|
||||
{
|
||||
spi_init(port, 2000 * 1000);
|
||||
spi_set_format(port, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
|
||||
|
||||
gpio_set_function(rx, GPIO_FUNC_SPI);
|
||||
gpio_set_function(sck, GPIO_FUNC_SPI);
|
||||
gpio_set_function(tx, GPIO_FUNC_SPI);
|
||||
//gpio_set_function(nss, GPIO_FUNC_SPI);
|
||||
|
||||
gpio_init(nss);
|
||||
gpio_set_dir(nss, GPIO_OUT);
|
||||
gpio_pull_up(nss);
|
||||
gpio_put(nss, 1);
|
||||
|
||||
gpio_init(rst);
|
||||
gpio_set_dir(rst, GPIO_OUT);
|
||||
gpio_pull_up(rst);
|
||||
gpio_put(rst, 1);
|
||||
|
||||
spi.port = port;
|
||||
spi.rst = rst;
|
||||
spi.nss = nss;
|
||||
spi.busy = busy;
|
||||
}
|
||||
|
||||
static inline void wait_not_busy()
|
||||
{
|
||||
while (gpio_get(spi.busy)) {
|
||||
sleep_us(10);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void wait_until_busy()
|
||||
{
|
||||
while (!gpio_get(spi.busy)) {
|
||||
sleep_us(10);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void begin_transmission()
|
||||
{
|
||||
wait_not_busy();
|
||||
gpio_put(spi.nss, 0);
|
||||
sleep_ms(10);
|
||||
}
|
||||
|
||||
static inline void end_transmission()
|
||||
{
|
||||
gpio_put(spi.nss, 1);
|
||||
sleep_ms(10);
|
||||
}
|
||||
|
||||
static pn5180_wait_loop_t wait_loop = NULL;
|
||||
|
||||
void pn5180_set_wait_loop(pn5180_wait_loop_t loop)
|
||||
{
|
||||
wait_loop = loop;
|
||||
}
|
||||
|
||||
static bool read_write(const uint8_t *data, uint8_t len, uint8_t *buf, uint8_t buf_len)
|
||||
{
|
||||
begin_transmission();
|
||||
spi_write_blocking(spi.port, data, len);
|
||||
end_transmission();
|
||||
|
||||
if (!buf || (buf_len == 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
begin_transmission();
|
||||
spi_read_blocking(spi.port, 0, buf, buf_len);
|
||||
end_transmission();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write_reg(uint8_t cmd, uint8_t reg, uint32_t v32)
|
||||
{
|
||||
uint8_t buf[] = { cmd, reg, v32 & 0xff, (v32 >> 8) & 0xff,
|
||||
(v32 >> 16) & 0xff, (v32 >> 24) & 0xff };
|
||||
return read_write(buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
void pn5180_write_reg(uint8_t reg, uint32_t v32)
|
||||
{
|
||||
write_reg(CMD_WRITE_REG, reg, v32);
|
||||
}
|
||||
|
||||
void pn5180_or_reg(uint8_t reg, uint32_t mask)
|
||||
{
|
||||
write_reg(CMD_WRITE_REG_OR, reg, mask);
|
||||
}
|
||||
|
||||
void pn5180_and_reg(uint8_t reg, uint32_t mask)
|
||||
{
|
||||
write_reg(CMD_WRITE_REG_AND, reg, mask);
|
||||
}
|
||||
|
||||
uint32_t pn5180_read_reg(uint8_t reg)
|
||||
{
|
||||
uint8_t buf[] = { CMD_READ_REG, reg };
|
||||
uint8_t out[4];
|
||||
read_write(buf, sizeof(buf), out, sizeof(out));
|
||||
return out[0] | (out[1] << 8) | (out[2] << 16) | (out[3] << 24);
|
||||
}
|
||||
|
||||
void pn5180_send_data(const uint8_t *data, uint8_t len, uint8_t last_bits)
|
||||
{
|
||||
uint8_t buf[len + 2];
|
||||
buf[0] = CMD_SEND_DATA;
|
||||
buf[1] = last_bits;
|
||||
memmove(buf + 2, data, len);
|
||||
read_write(buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
void pn5180_read_data(uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint8_t buf[] = { CMD_READ_DATA, 0x00 };
|
||||
read_write(buf, sizeof(buf), data, len);
|
||||
}
|
||||
|
||||
void pn5180_read_eeprom(uint8_t addr, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t cmd[3] = { CMD_READ_EEPROM, addr, len };
|
||||
read_write(cmd, sizeof(cmd), buf, len);
|
||||
}
|
||||
|
||||
void pn5180_load_rf_config(uint8_t tx_cfg, uint8_t rx_cfg)
|
||||
{
|
||||
uint8_t buf[] = { CMD_LOAD_RF_CONFIG, tx_cfg, rx_cfg};
|
||||
read_write(buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
void pn5180_rf_on()
|
||||
{
|
||||
uint8_t buf[] = { CMD_RF_ON, 0 };
|
||||
read_write(buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
void pn5180_rf_off()
|
||||
{
|
||||
uint8_t buf[] = { CMD_RF_OFF, 0 };
|
||||
read_write(buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
void pn5180_reset()
|
||||
{
|
||||
gpio_put(spi.rst, 0);
|
||||
sleep_ms(10);
|
||||
gpio_put(spi.rst, 1);
|
||||
sleep_ms(10);
|
||||
while (pn5180_read_reg(PN5180_REG_IRQ_STATUS) & (1 << 2)) {
|
||||
printf("irq: %08lx\n", pn5180_read_reg(PN5180_REG_IRQ_STATUS));
|
||||
}
|
||||
|
||||
pn5180_write_reg(PN5180_REG_IRQ_CLEAR, 0xffffffff); // clear all flags
|
||||
}
|
||||
|
||||
void pn5180_print_rf_cfg()
|
||||
{
|
||||
printf("RF_CONTROL_TX_CLK: %08lx\n", pn5180_read_reg(0x21));
|
||||
printf("TX_DATA_MOD: %08lx\n", pn5180_read_reg(0x16));
|
||||
printf("TX_UNDERSHOOT_CFG: %08lx\n", pn5180_read_reg(0x14));
|
||||
printf("TX_OVERSHOOT_CFG: %08lx\n", pn5180_read_reg(0x15));
|
||||
printf("RF_CONTROL_TX: %08lx\n", pn5180_read_reg(0x20));
|
||||
printf("ANT_CONTROL: %08lx\n", pn5180_read_reg(0x29));
|
||||
}
|
44
firmware/src/pn5180.h
Normal file
44
firmware/src/pn5180.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* PN5180 NFC Reader
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PN5180_H
|
||||
#define PN5180_H
|
||||
|
||||
#include "hardware/spi.h"
|
||||
|
||||
#define PN5180_REG_SYSTEM_CONFIG 0x00
|
||||
#define PN5180_REG_IRQ_ENABLE 0x01
|
||||
#define PN5180_REG_IRQ_STATUS 0x02
|
||||
#define PN5180_REG_IRQ_CLEAR 0x03
|
||||
#define PN5180_REG_RX_STATUS 0x13
|
||||
#define PN5180_REG_RF_STATUS 0x1d
|
||||
#define PN5180_REG_CRC_RX_CONFIG 0x12
|
||||
#define PN5180_REG_CRC_TX_CONFIG 0x19
|
||||
|
||||
typedef void (*pn5180_wait_loop_t)();
|
||||
|
||||
void pn5180_set_wait_loop(pn5180_wait_loop_t loop);
|
||||
|
||||
void pn5180_init(spi_inst_t *port, uint8_t rx, uint8_t sck, uint8_t tx,
|
||||
uint8_t rst, uint8_t nss, uint8_t busy);
|
||||
|
||||
void pn5180_write_reg(uint8_t reg, uint32_t v32);
|
||||
void pn5180_or_reg(uint8_t reg, uint32_t mask);
|
||||
void pn5180_and_reg(uint8_t reg, uint32_t mask);
|
||||
uint32_t pn5180_read_reg(uint8_t reg);
|
||||
void pn5180_send_data(const uint8_t *data, uint8_t len, uint8_t last_bits);
|
||||
void pn5180_read_data(uint8_t *data, uint8_t len);
|
||||
void pn5180_read_eeprom(uint8_t addr, uint8_t *buf, uint8_t len);
|
||||
|
||||
void pn5180_load_rf_config(uint8_t tx_cfg, uint8_t rx_cfg);
|
||||
void pn5180_rf_on();
|
||||
void pn5180_rf_off();
|
||||
|
||||
void pn5180_reset();
|
||||
|
||||
void pn5180_print_rf_cfg();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user