bool SD::ReadBlock(uint32_t unBlockNum, uint8_t *punBuffer) { uint8_t unResp; uint16_t retry; if (!m_bCardInitialized) {return false;} if (m_eCardType = SD_CARD_TYPE_SDSC) {unBlockNum <<= 9;} /* SDSC use byte address, SDHC and SDXC use block address */ if (SendCommand(SD_CMD_READ_SINGLE_BLOCK, unBlockNum, 0xFF) != R1_NO_ERROR) {return false;} /* 0x00 = OK, else error */ spi_cs_enable(SD_PORT); /* Wait for data token 0xFE */ do { spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); if (retry++ > 0xFFFE) {spi_cs_disable(SD_PORT); return false;} } while (unResp != 0xFE); //while (spi_send(SD_SPI,0xFF) != 0xFE) {if (retry++ > 0xFFFE) {spi_cs_disable(SD_PORT); return false;};} /* Read data from block */ for (uint16_t i=0; i<SD_BLOCK_SIZE; i++) { spi_send(SD_SPI,0xFF); punBuffer[i] = spi_read(SD_SPI); } /* Last 2 bytes CRC */ spi_send(SD_SPI,0xFF); spi_send(SD_SPI,0xFF); spi_cs_disable(SD_PORT); return true; }
uint32_t LIS2DH12_Read_Data(uint8_t addr, uint8_t data[], uint8_t len) { uint8_t i; uint8_t cmd; if(len == 0) return 2; spi_clear_flog(); spi_cs_enable(); cmd = 0x80 | 0x40 | addr; LIS2DH12_Write(cmd); LIS2DH12_RW(INVAILVALUE); for(i=1; i<len; i++) { data[i-1] = LIS2DH12_RW(INVAILVALUE); } data[i-1] = LIS2DH12_Read(); spi_cs_disable(); return 0; }
inline void MFRC522::WriteReg(REG_enum eReg, uint8_t *unData, uint8_t unLen) { spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,(eReg<<1)&~WRITE_REG_SIG); /* Register address with WRITE signature */ for (uint8_t i=0; i<unLen; i++) {spi_send(MFRC522_SPI,*(unData+i));} /* Send data */ spi_cs_disable(MFRC522_PORT); }
inline void MFRC522::WriteReg(REG_enum eReg, uint8_t unData) { spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,(eReg<<1)&~WRITE_REG_SIG); /* Register address with WRITE signature */ spi_send(MFRC522_SPI,unData); /* Send data */ spi_cs_disable(MFRC522_PORT); }
inline void MFRC522::ClrRegBitMask(REG_enum eReg, uint8_t unBitMask) { uint8_t unValue; spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,(eReg<<1)|READ_REG_SIG); /* Register address with READ signature */ spi_send(MFRC522_SPI,0xFF); /* No operation, next clock cycle */ unValue = spi_read(MFRC522_SPI); /* Read value in register */ spi_cs_disable(MFRC522_PORT); unValue &= ~unBitMask; spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,(eReg<<1)&~WRITE_REG_SIG); /* Register address with WRITE signature */ spi_send(MFRC522_SPI,unValue); /* Send data */ spi_cs_disable(MFRC522_PORT); }
bool SD::WriteBlock(uint32_t unBlockNum, uint8_t *punBuffer) { uint8_t unResp; uint16_t retry; if (!m_bCardInitialized) {return false;} if (m_eCardType = SD_CARD_TYPE_SDSC) {unBlockNum <<= 9;} /* SDSC use byte address, SDHC and SDXC use block address */ if (SendCommand(SD_CMD_WRITE_SINGLE_BLOCK, unBlockNum, 0xFF) != R1_NO_ERROR) {return false;} /* 0x00 = OK, else error */ spi_cs_enable(SD_PORT); /* dummy */ spi_send(SD_SPI,0xFF); /* Send data token */ spi_send(SD_SPI,0xFE); /* Send data to sd card from buffer */ for (uint16_t i=0; i<SD_BLOCK_SIZE; i++) {spi_send(SD_SPI,punBuffer[i]);} /* Last 2 bytes dummy CRC */ spi_send(SD_SPI,0xFF); spi_send(SD_SPI,0xFF); /* Check if data accepted from sd card */ spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); if ((unResp & DATA_ANSWER_bm) != DATA_ACCEPT_gc) {spi_cs_disable(SD_PORT); return false;} spi_send(SD_SPI,0xFF); /* Wait until data written */ do { spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); if (retry++ > 0xFFFE) {spi_cs_disable(SD_PORT); return false;} } while (!unResp); //while (!spi_send(SD_SPI,0xFF)) {if (retry++ > 0xFFFE) {spi_cs_disable(SD_PORT); return false;};} spi_cs_disable(SD_PORT); return true; }
inline uint8_t MFRC522::ReadReg(REG_enum eReg) { uint8_t unValue; spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,(eReg<<1)|READ_REG_SIG); /* Register address with READ signature */ spi_send(MFRC522_SPI,0xFF); /* No operation, next clock cycle */ unValue = spi_read(MFRC522_SPI); /* Read value in register */ spi_cs_disable(MFRC522_PORT); return unValue; }
uint32_t LIS2DH12_Write_Reg(uint8_t addr, uint8_t value) { spi_clear_flog(); spi_cs_enable(); LIS2DH12_Write(addr & (~0x80)); LIS2DH12_RW(value); LIS2DH12_Read(); spi_cs_disable(); return 0; }
inline void MFRC522::ReadReg(REG_enum eReg, uint8_t unNum, uint8_t *punBuffer) { uint8_t unAddress; unAddress = (uint8_t)eReg; spi_cs_enable(MFRC522_PORT); spi_send(MFRC522_SPI,((unAddress++)<<1)|READ_REG_SIG); /* Register address with READ signature */ for (unNum; unNum>0; unNum--) { spi_send(MFRC522_SPI,((unAddress++)<<1)|READ_REG_SIG); /* Next address, next clock cycle */ *(punBuffer++) = spi_read(MFRC522_SPI); /* Read value in register */ } spi_cs_disable(MFRC522_PORT); return; }
uint8_t LIS2DH12_Read_Reg(uint8_t addr) { uint8_t RX; uint8_t cmd; spi_clear_flog(); spi_cs_enable(); cmd = 0x80 | addr; cmd &= ~0x40; LIS2DH12_Write(cmd); LIS2DH12_RW(INVAILVALUE); RX = LIS2DH12_Read(); spi_cs_disable(); return RX; }
uint32_t LIS2DH12_Init(void) { //config nrf51822 spi interface nrf_gpio_cfg_output(LIS2DH12_Init_Struct.CSN); //CS spi_cs_disable(); LIS2DH12_SPI_INTERFACE->PSELMISO = LIS2DH12_Init_Struct.MISO; //MISO LIS2DH12_SPI_INTERFACE->PSELMOSI = LIS2DH12_Init_Struct.MOSI; //MOSI LIS2DH12_SPI_INTERFACE->PSELSCK = LIS2DH12_Init_Struct.SCK; //SCK //config frequency LIS2DH12_SPI_INTERFACE->FREQUENCY = LIS2DH12_Init_Struct.FREQUENCY; //config config LIS2DH12_SPI_INTERFACE->CONFIG = (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos)| (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos)| (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); //enable nrf51822 spi interface LIS2DH12_SPI_INTERFACE->ENABLE = SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos; return 0; }
R1_ERROR_enum SD::SendCommand(SD_CMD_enum eCmd, uint32_t unAttrib, uint8_t unCrc) { R1_ERROR_enum eResp = R1_INVALID_ERROR_bm; uint8_t retry; spi_cs_enable(SD_PORT); spi_send(SD_SPI,0x40|eCmd); spi_send(SD_SPI,(uint8_t)(unAttrib>>24)); spi_send(SD_SPI,(uint8_t)(unAttrib>>16)); spi_send(SD_SPI,(uint8_t)(unAttrib>>8)); spi_send(SD_SPI,(uint8_t)(unAttrib)); spi_send(SD_SPI,unCrc); /* Wait for response */ while(eResp == R1_INVALID_ERROR_bm) { spi_send(SD_SPI,0xFF); eResp = (R1_ERROR_enum)spi_read(SD_SPI); if (retry++ > 0xFE) {break;} } spi_cs_disable(SD_PORT); spi_send(SD_SPI,0xFF); /* DUMMY */ return eResp; }
SD::SD() { uint8_t retry = 0; /* Setup pins direction */ spi_set_master_port_dir(SD_PORT); #ifdef COMPILE_SD_INSERT_DETECT /* Setup SD switch pin */ SD_PORT.DIRCLR = 1<<SD_SWITCH_PIN; SD_PORT.INT0MASK = 1<<SD_SWITCH_PIN; SD_PORT.INTCTRL = PORT_INT0LVL_LO_gc; SD_PORT.PIN1CTRL = PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; #endif spi_cs_disable(SD_PORT); spi_set_mode(SD_SPI,SPI_MODE_0_gc); spi_set_dord(SD_SPI,SPI_DORD_MSB_FIRST); spi_enable_master(SD_SPI); while ((retry++<10) && !m_bCardInitialized) {Init();} }
bool SD::Init() { uint8_t retry; R1_ERROR_enum eR1resp; uint8_t unResp; m_bCardInitialized = false; m_eCardType = SD_CARD_TYPE_NONE; /* Set low clock 400kHz */ /* Clear prescaler */ SD_SPI.CTRL &= ~(SPI_PRESCALER_gm); SD_SPI.CTRL &= ~(1<<SPI_CLK2X_bp); /* Baudrate */ #if (400000 <= F_CPU/128) SD_SPI.CTRL |= SPI_PRESCALER_DIV128_gc; #elif (400000 <= F_CPU/64) SD_SPI.CTRL |= SPI_PRESCALER_DIV64_gc; #elif (400000 <= F_CPU/32) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV64_gc; #elif (400000 <= F_CPU/16) SD_SPI.CTRL |= SPI_PRESCALER_DIV16_gc; #elif (400000 <= F_CPU/8) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV16_gc; #elif (400000 <= F_CPU/4) SD_SPI.CTRL |= SPI_PRESCALER_DIV4_gc; #elif (400000 <= F_CPU/2) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #else SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #endif /* 80 clock cycles */ spi_cs_enable(SD_PORT); for (uint8_t i=0;i<10;i++) {spi_send(SD_SPI,0xFF);} spi_cs_disable(SD_PORT); /* Reset and go idle */ if (!(SendCommand(SD_CMD_GO_IDLE_STATE,0,0x95) & R1_IDLE_STATE_bm)) {return m_bCardInitialized;} if (!(SendCommand(SD_CMD_SEND_IF_COND,0x1AA,0x87) & R1_IDLE_STATE_bm)) {return m_bCardInitialized;} SendCommand(SD_CMD_APP_CMD,0,0xFF); /* Wait for initialization (0x00 = OK, else error)*/ do { eR1resp = SendCommand(SD_CMD_SEND_OP_COND,0x40000000,0xFF); /* ACMD41 */ if (retry++ > 0xFE) {return m_bCardInitialized;} } while (eR1resp != R1_NO_ERROR); /* Set CRC off */ if (SendCommand(SD_CMD_CRC_ON_OFF,0,0xFF) != R1_NO_ERROR) {return m_bCardInitialized;} /* Set Block length */ if (SendCommand(SD_CMD_SET_BLOCK_LEN,SD_BLOCK_SIZE, 0xFF) != R1_NO_ERROR) {return m_bCardInitialized;} /* Read OCR register - check type of card */ spi_cs_enable(SD_PORT); spi_send(SD_SPI,0x40|SD_CMD_READ_OCR); spi_send(SD_SPI,0x00); spi_send(SD_SPI,0x00); spi_send(SD_SPI,0x00); spi_send(SD_SPI,0x00); spi_send(SD_SPI,0xFF); /* Wait for response */ do { spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); if (retry++ > 0xFE) {break;} } while(unResp == 0xFF); //while(spi_send(SD_SPI,0xFF) == 0xFF) {if (retry++ > 0xFE) {break;}} /* OCR - 4 bytes (MSB first) */ spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); if (unResp & 0x40) {m_eCardType = SD_CARD_TYPE_SDHC_SDXC;} else {m_eCardType = SD_CARD_TYPE_SDSC;} spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); spi_send(SD_SPI,0xFF); unResp = spi_read(SD_SPI); spi_cs_disable(SD_PORT); /* Set back to full baud rate */ /* Clear prescaler */ SD_SPI.CTRL &= ~(SPI_PRESCALER_gm); SD_SPI.CTRL &= ~(1<<SPI_CLK2X_bp); /* Baud rate */ #if (SD_BAUD <= F_CPU/128) SD_SPI.CTRL |= SPI_PRESCALER_DIV128_gc; #elif (SD_BAUD <= F_CPU/64) SD_SPI.CTRL |= SPI_PRESCALER_DIV64_gc; #elif (SD_BAUD <= F_CPU/32) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV64_gc; #elif (SD_BAUD <= F_CPU/16) SD_SPI.CTRL |= SPI_PRESCALER_DIV16_gc; #elif (SD_BAUD <= F_CPU/8) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV16_gc; #elif (SD_BAUD <= F_CPU/4) SD_SPI.CTRL |= SPI_PRESCALER_DIV4_gc; #elif (SD_BAUD <= F_CPU/2) SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #else SD_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #endif return (m_bCardInitialized = true); }
MFRC522::MFRC522() { /* Set Reset pin */ MFRC522_PORT.OUTCLR = 1<<MFRC522_RESET_PIN; /* Reset on */ MFRC522_PORT.DIRSET = 1<<MFRC522_RESET_PIN; /* Set as output */ MFRC522_PORT.OUTSET = 1<<MFRC522_RESET_PIN; /* Reset off */ /* Setup SPI driver */ spi_set_master_port_dir(MFRC522_PORT); spi_cs_disable(MFRC522_PORT); spi_set_mode(MFRC522_SPI,SPI_MODE_0_gc); spi_set_dord(MFRC522_SPI,SPI_DORD_MSB_FIRST); spi_enable_master(MFRC522_SPI); /* Set SPI Baudrate */ #if (MFRC522_BAUD <= F_CPU/128) MFRC522_SPI.CTRL |= SPI_PRESCALER_DIV128_gc; #elif (MFRC522_BAUD <= F_CPU/64) MFRC522_SPI.CTRL |= SPI_PRESCALER_DIV64_gc; #elif (MFRC522_BAUD <= F_CPU/32) MFRC522_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV64_gc; #elif (MFRC522_BAUD <= F_CPU/16) MFRC522_SPI.CTRL |= SPI_PRESCALER_DIV16_gc; #elif (MFRC522_BAUD <= F_CPU/8) MFRC522_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV16_gc; #elif (MFRC522_BAUD <= F_CPU/4) MFRC522_SPI.CTRL |= SPI_PRESCALER_DIV4_gc; #elif (MFRC522_BAUD <= F_CPU/2) MFRC522_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #else MFRC522_SPI.CTRL |= 1<<SPI_CLK2X_bp|SPI_PRESCALER_DIV4_gc; #endif /* Set interrupt on pin MFRC522_IRQ_PIN */ MFRC522_PORT.INT0MASK = 1<<MFRC522_IRQ_PIN; MFRC522_PORT.INTCTRL = PORT_INT0LVL_HI_gc; #if MFRC522_IRQ_PIN == 0 MFRC522_PORT.PIN0CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 1 MFRC522_PORT.PIN1CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 2 MFRC522_PORT.PIN2CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 3 MFRC522_PORT.PIN3CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 4 MFRC522_PORT.PIN4CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 5 MFRC522_PORT.PIN5CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 6 MFRC522_PORT.PIN6CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #elif MFRC522_IRQ_PIN == 7 MFRC522_PORT.PIN7CTRL = PORT_ISC_FALLING_gc|PORT_OPC_PULLUP_gc; #endif for (uint16_t i=0; i<0x7FFF; i++); /* Wait routine until oscillator is ready. t >= 37.74us */ WriteReg(REG_CommandReg,COMM_SoftReset); /* Soft Reset */ WriteReg(REG_TModeReg, 0x80); /* TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds */ WriteReg(REG_TPrescalerReg, 0xA9); /* TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25us. */ WriteReg(REG_TReloadRegH, 0x03); /* Reload timer with 0x3E8 = 1000, ie 25ms before timeout. */ WriteReg(REG_TReloadRegL, 0xe8); WriteReg(REG_TxASKReg, 0x40); /* Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting */ WriteReg(REG_ModeReg, 0x3D); /* Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4) */ AntennaOn(); }