/*---------------------------------------------------------------------------
COMPANY : WS
DATE : 20190328
AUTHOR : LI
IC : HT32F030C8T6
DESCRIPTION : SPI com PN512 read and write M1 Card,KAYA can change,only check
KEYA to write, read by KAYA or KEYB check
___________________________________________________________________________
REVISION Date
1.0 20190328
___________________________________________________________________________
---------------------------------------------------------------------------*/
#include "main.h"
#include "stdio.h"
#include <string.h>
#define Set_NSS HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
#define Clr_NSS HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
const u8 DefaultKeyABuf[6] ={ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };//{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };//
u8 KeyABuf[6] ={ 0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6 };//{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };//
const u8 DefaultKeyBBuf[6] ={ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };//{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };//
u8 CardRevBuf[16] = { 0 };
u8 Pn512ErrCode;
/*---------------------------------------------------------------------------
Function : TestDelay
Description :
Input : m
Output : None
Return : None
Note : None
---------------------------------------------------------------------------*/
void TestDelay(u16 m)
{
u16 k;
for(k=0;k<m;k++);
}
/*---------------------------------------------------------------------------
Function : spi1_init
Description :
Input : None
Output : None
Return : None
Note : None
---------------------------------------------------------------------------*/
void spi1_init(void)
{
SPI_HandleTypeDef SpiHandle;
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; // spi_clk spi_miso spi_mosi
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_4; // NSS
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_2; // pn512 reset
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_0; // pn512 IRQ
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_RCC_SPI1_CLK_ENABLE();
SpiHandle.Instance = SPI1;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
{
/* Initialization Error */
while(1);
}
__HAL_SPI_ENABLE(&SpiHandle);
}
/*---------------------------------------------------------------------------
Function : spi1_write
Description : write to one byte to PN512
Input : addr PN512 register address, value write data,
Output : None
Return : PN512 register address
Note : None
---------------------------------------------------------------------------*/
u8 spi1_write(u8 addr, u8 value)
{
u8 temp;
Clr_NSS;
*(__IO uint8_t *)&SPI1->DR = ((addr<<1)&0x7E);
while((SPI1->SR&0x01)==0x00);
temp= SPI1->DR;
*(__IO uint8_t *)&SPI1->DR = value;
while((SPI1->SR&0x01)==0x00);
temp= SPI1->DR;
Set_NSS;
return temp;
}
/*---------------------------------------------------------------------------
Function : spi1_read
Description : read to one byte from PN512
Input : addr PN512 register address
Output : None
Return : PN512 addr register
Note : None
---------------------------------------------------------------------------*/
u8 spi1_read(u8 addr)
{
u8 temp;
Clr_NSS;
*(__IO uint8_t *)&SPI1->DR = ((addr<<1)&0x7E)|0x80;
while((SPI1->SR&0x01)==0x00);
temp= SPI1->DR;
*(__IO uint8_t *)&SPI1->DR = 0xFF;
while((SPI1->SR&0x01)==0x00);
temp= SPI1->DR;
Set_NSS;
return temp;
}
/*---------------------------------------------------------------------------
Function : ClearBitMask
Description : Clear bit to PN512 register
Input : addr PN512 register address,mask Bit to clear
Output : None
Return : None
Note : None
---------------------------------------------------------------------------*/
void ClearBitMask(u8 addr,u8 mask)
{
u8 tmp = 0x00;
tmp = spi1_read(addr);
spi1_write(addr, tmp & ~mask); // clear bit mask
}
/*---------------------------------------------------------------------------
Function : SetBitMask
Description : Set bit to PN512 register
Input : addr PN512 register address,mask Bit to set
Output : None
Return : None
Note : None
---------------------------------------------------------------------------*/
void SetBitMask(u8 addr,u8 mask)
{
u8 tmp = 0x00;
tmp = spi1_read(addr);
spi1_write(addr,tmp | mask); // set bit mask
}
/*---------------------------------------------------------------------------
Function : SetBitMask
Description : Calulate CRC
Input : pIndata, len PN512,
Output : pOutData
Return : None
Note : None
---------------------------------------------------------------------------*/
void CalulateCRC(u8 *pIndata,u8 len,u8 *pOutData)
{
u8 i,n;
ClearBitMask(DivIrqReg,0x04);
spi1_write(CommandReg,PCD_IDLE);
SetBitMask(FIFOLevelReg,0x80);
for (i=0; i<len; i++)
{
spi1_write(FIFODataReg, *(pIndata+i)); }
spi1_write(CommandReg, PCD_CALCCRC);
i = 0xFF;
do
{
n = spi1_read(DivIrqReg);
i--;
}
while ((i!=0) && !(n&0x04));
pOutData[0] = spi1_read(CRCResultRegL);
pOutData[1] = spi1_read(CRCResultRegM);
}
/*---------------------------------------------------------------------------
Function : PcdComPN512
Description :
Input : Command, pInData,InLenByte
Output : pOutData, pOutLenBit
Return : MI_OK or MI_NOTAGERR orMI_ERR
Note :
---------------------------------------------------------------------------*/
u8 PcdComPN512(u8 Command, u8 *pInData, u8 InLenByte,u8 *pOutData, u16 *pOutLenBit)
{
u8 PN512_status = MI_ERR;
u8 irqEn = 0x00;
u8 waitFor = 0x00;
u8 lastBits;
u8 n;
u16 i;
switch (Command)
{
case PCD_AUTHENT:
irqEn = 0x12;
waitFor = 0x10;
break;
case PCD_TRANSCEIVE:
irqEn = 0x77;
waitFor = 0x30;
break;
default:
break;
}
spi1_write(ComIEnReg,irqEn|0x80);
ClearBitMask(ComIrqReg,0x80);
spi1_write(CommandReg,P