/** * \brief Write to the FRAM chip. * \param address The index of the byte to start writing to. * \param len The number of bytes to write. * \param buf A buffer of values to write. * \return 0 on success, -1 on error * * Writes len bytes to the FRAM chip starting at address. */ int fm25v02_write(uint16_t address, uint16_t len, uint8_t *buf) { uint16_t i; spi_set_mode(SSI_CR0_FRF_MOTOROLA, SSI_CR0_SPO, SSI_CR0_SPH, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); /* Send the WRITE ENABLE command to allow writing to the FRAM */ SPI_WRITE(FM25V02_WRITE_ENABLE_COMMAND); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); /* Send the WRITE command and the address to the FRAM */ SPI_WRITE(FM25V02_WRITE_COMMAND); address &= 0x7fff; SPI_WRITE((address&0xff00)>>8); SPI_WRITE((address&0xff)); /* Send the data to write */ for(i=0; i<len; i++) { SPI_WRITE(buf[i]); } SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); return 0; }
/******************************************************************************* Description: Write via serial SPI interface Arguments: pDev - pointer to the device structure pData - pointer to the write buffer count - number of words to write, must be greater than 0 Return: IFX_SUCCESS if successful, otherwise IFX_ERROR *******************************************************************************/ IFX_int32_t serial_write (VINETIC_DEVICE *pDev, IFX_uint16_t *pData, IFX_int32_t count) { IFX_int32_t ret = IFX_SUCCESS; IFX_uint32_t nSend = 0, len = 0; /* set CSQ = LOW */ SPI_CS_SET(IFX_LOW); /* write all data */ while ((nSend != (count * 2)) && (ret != IFX_ERROR)) { if (((count * 2) - nSend) > SPI_MAXBYTES_SIZE) len = SPI_MAXBYTES_SIZE; else len = ((count * 2) - nSend); ret = spi_ll_read_write ((IFX_uint8_t *)&pData [nSend/2], len, NULL, 0); /* increase send count */ nSend += ret; } /* Set CSQ = HIGH */ SPI_CS_SET(IFX_HIGH); /* recover */ IFXOS_DELAYUS (VINETIC_SPI_RECOVERY_TIME); if (ret != IFX_ERROR) ret = IFX_SUCCESS; return ret; }
/******************************************************************************* Description: Direct chip access for reading DIOP commands via serial SPI interface Arguments: pDev - pointer to the device structure pCmd - pointer to the write buffer, size 2 words pData - pointer to read Data count - number of words to read Return: IFX_SUCCESS if successful, otherwise IFX_ERROR *******************************************************************************/ IFX_int32_t serial_diop_read (VINETIC_DEVICE *pDev, IFX_uint16_t *pCmd, IFX_uint16_t *pData, IFX_int32_t count) { IFX_int32_t ret = IFX_SUCCESS; IFX_uint8_t pSpiRead [SPI_MAXBYTES_SIZE]; IFX_uint32_t nRev = 0; /* set CSQ = LOW */ SPI_CS_SET(IFX_LOW); /* do read operation, considering dummy word in the size to read */ nRev = spi_ll_read_write ((IFX_uint8_t *)pCmd, 4, pSpiRead, ((count + 1) * 2)); /* Set CSQ = HIGH */ SPI_CS_SET(IFX_HIGH); /* Recovery time */ IFXOS_DELAYUS (VINETIC_SPI_RECOVERY_TIME); /* copy data without dummy into user buffer */ if (nRev == ((count+1) *2)) { memcpy(pData, &pSpiRead[2], (count * 2)); /* cpb2w(pData, &pSpiRead[2], (count * 2)); */ } else ret = IFX_ERROR; return ret; }
/** * \brief Write to the FRAM chip. * \param address The index of the byte to start writing to. * \param len The number of bytes to write. * \param buf A buffer of values to write. * \return 0 on success, -1 on error * * Writes len bytes to the FRAM chip starting at address. */ int fm25lb_write(uint16_t address, uint16_t len, uint8_t *buf) { uint16_t i; spi_set_mode(SSI_CR0_FRF_MOTOROLA, SSI_CR0_SPO, SSI_CR0_SPH, 8); SPI_CS_CLR(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); /* Send the WRITE ENABLE command to allow writing to the FRAM */ SPI_WRITE(FM25LB_WRITE_ENABLE_COMMAND); SPI_CS_SET(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); SPI_CS_CLR(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); /* Send the WRITE command and the address to the FRAM */ SPI_WRITE(FM25LB_ADD_ADDRESS_BIT(address, FM25LB_WRITE_COMMAND)); SPI_WRITE(address & 0xFF); /* Send the data to write */ for(i=0; i<len; i++) { SPI_WRITE(buf[i]); } SPI_CS_SET(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); return 0; }
/******************************************************************************* Description: read via serial SPI interface Arguments: pDev - pointer to the device structure cmd - short command which allow a specific reading pData - pointer to the read buffer count - number of words to read, must be greater than 0 Return: IFX_SUCCESS if successful, otherwise IFX_ERROR *******************************************************************************/ IFX_int32_t serial_read (VINETIC_DEVICE *pDev, IFX_uint16_t cmd, IFX_uint16_t *pData, IFX_int32_t count) { IFX_int32_t ret = IFX_SUCCESS; IFX_uint16_t dummy = 0; IFX_uint32_t nRev = 0, len = 0; /* set CSQ = LOW */ SPI_CS_SET(IFX_LOW); /* write command for reading and read dummy word */ ret = spi_ll_read_write ((IFX_uint8_t *)&cmd, 2, (IFX_uint8_t *)&dummy, 2); /* read Data */ while ((nRev != (count* 2)) && (ret != IFX_ERROR)) { if (((count * 2) - nRev) > SPI_MAXBYTES_SIZE) len = SPI_MAXBYTES_SIZE; else len = ((count * 2) - nRev); ret = spi_ll_read_write (NULL, 0, (IFX_uint8_t *)&pData [nRev/2], len); /* increase receive count */ nRev += ret; } /* Set CSQ = HIGH */ SPI_CS_SET(IFX_HIGH); /* recover */ IFXOS_DELAYUS (VINETIC_SPI_RECOVERY_TIME); if (ret != IFX_ERROR) ret = IFX_SUCCESS; return ret; }
int fm25v02_writeStatus(uint8_t statusReg){ // Set WEL bit in status register spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_WRITE_ENABLE_COMMAND); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_WRITE_STATUS_COMMAND); SPI_WRITE(statusReg); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); return 0; }
int rv3049_set_time(rv3049_time_t* time) { uint8_t buf[8]; int i; buf[0] = rv3049_binary_to_bcd(time->seconds); buf[1] = rv3049_binary_to_bcd(time->minutes); buf[2] = rv3049_binary_to_bcd(time->hours); // 24 hour mode buf[3] = rv3049_binary_to_bcd(time->days); buf[4] = time->weekday; buf[5] = time->month; buf[6] = rv3049_binary_to_bcd(time->year - 2000); spix_set_mode(SPI_CONF_DEFAULT_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, SSI_CR0_SPH, 8); SPI_CS_SET(RV3049_CS_PORT_NUM, RV3049_CS_PIN); // Signal a write to the clock SPI_WRITE(RV3049_SET_WRITE_BIT(RV3049_PAGE_ADDR_CLOCK)); // Write the clock values for (i=0; i<RV3049_WRITE_LEN_TIME; i++) { SPI_WRITE(buf[i]); } SPI_CS_CLR(RV3049_CS_PORT_NUM, RV3049_CS_PIN); return 0; }
/** * \brief Read from the FRAM chip. * \param address The index of the byte to start reading from. * \param len The number of bytes to read. * \param buf A buffer to put the return data in. * \return 0 on success, -1 on error * * Reads len bytes from the FRAM chip starting at address. */ int fm25lb_read(uint16_t address, uint16_t len, uint8_t *buf) { uint16_t i; // uint16_t c; // uint16_t cycles = (len / 6) + 1; // uint16_t index = 0; uint16_t current_address = address; spi_set_mode(SSI_CR0_FRF_MOTOROLA, SSI_CR0_SPO, SSI_CR0_SPH, 8); SPI_CS_CLR(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); /* Send the READ command and the address to the FRAM */ SPI_WRITE(FM25LB_ADD_ADDRESS_BIT(current_address, FM25LB_READ_COMMAND)); SPI_WRITE(current_address & 0xFF); SPI_FLUSH(); for (i=0; i<len; i++) { SPI_READ(buf[i]); } SPI_CS_SET(FM25LB_CS_N_PORT_NUM, FM25LB_CS_N_PIN); return 0; }
/** * \brief Read from the FRAM chip. * \param address The index of the byte to start reading from. * \param len The number of bytes to read. * \param buf A buffer to put the return data in. * \return 0 on success, -1 on error * * Reads len bytes from the FRAM chip starting at address. */ int fm25v02_read(uint16_t address, uint16_t len, uint8_t *buf) { uint16_t i; spi_set_mode(SSI_CR0_FRF_MOTOROLA, SSI_CR0_SPO, SSI_CR0_SPH, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); /* Send the READ command and the address to the FRAM */ SPI_WRITE(FM25V02_READ_COMMAND); address &= 0x7fff; SPI_WRITE((address&0xff00)>>8); SPI_WRITE((address&0xff)); SPI_FLUSH(); for (i=0; i<len; i++) { SPI_READ(buf[i]); } SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); return 0; }
void nrf51822_interrupt(uint8_t port, uint8_t pin) { uint16_t b; uint8_t buf[256]; int i; leds_toggle(LEDS_RED); spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(8); // READ_IRQ SPI_WRITE(0x01); SPI_FLUSH(); SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(75); SPI_CS_CLR(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(8); SPI_READ(b); if (b == 0xFF) { // ERROR on the nrf51822 side. Skip this. } else { for (i=0; i<b; i++) { SPI_READ(buf[i]); } } SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); }
uint8_t fm25v02_readStatus(){ uint8_t statusReg; spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_READ_STATUS_COMMAND); SPI_FLUSH(); SPI_READ(statusReg); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); return statusReg; }
void fm25v02_eraseAll(){ uint16_t i; spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_WRITE_ENABLE_COMMAND); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_WRITE_COMMAND); // Address SPI_WRITE(0x00); SPI_WRITE(0x00); /* Send the data to write */ for(i=0; i<0x7fff; i++) { SPI_WRITE(0x00); } SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); }
void fm25v02_dummyWakeup(){ uint8_t dummyReg; //uint16_t dummyCnt; spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); // Delay for 400-ish us clock_delay_usec(400); //for (dummyCnt=0; dummyCnt<800; dummyCnt++) // asm("nop"); SPI_FLUSH(); SPI_READ(dummyReg); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); }
void nrf51822_get_all_advertisements () { //spi_set_mode(SSI_CR0_FRF_MOTOROLA, SSI_CR0_SPO, SSI_CR0_SPH, 8); spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); clock_delay_usec(8); // GET ADVERTISEMENTS SPI_WRITE(0x02); SPI_FLUSH(); SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); }
/** * \brief Initialize the nRF51822. */ void nrf51822_init() { // Setup interrupt from nRF51822 GPIO_SOFTWARE_CONTROL(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_SET_INPUT(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_DETECT_EDGE(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_TRIGGER_SINGLE_EDGE(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_DETECT_RISING(NRF51822_INT_BASE, NRF51822_INT_MASK); GPIO_ENABLE_INTERRUPT(NRF51822_INT_BASE, NRF51822_INT_MASK); ioc_set_over(NRF51822_INT_PORT_NUM, 0, IOC_OVERRIDE_DIS); nvic_interrupt_enable(NVIC_INT_GPIO_PORT_B); gpio_register_callback(nrf51822_interrupt, NRF51822_INT_PORT_NUM, NRF51822_INT_PIN); spi_cs_init(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); SPI_CS_SET(NRF51822_CS_N_PORT_NUM, NRF51822_CS_N_PIN); }
/** * \brief Initialize the FM25V02. */ void fm25v02_init() { #if defined(VERSION9) || defined(VERSION10) || defined(VERSION11) /* Set the HOLD_N and WP_N pins to outputs and high */ GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(FM25V02_HOLD_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_HOLD_N_PIN)); GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(FM25V02_WP_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_WP_N_PIN)); GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(FM25V02_HOLD_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_HOLD_N_PIN)); GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(FM25V02_WP_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_WP_N_PIN)); GPIO_SET_PIN(GPIO_PORT_TO_BASE(FM25V02_HOLD_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_HOLD_N_PIN)); GPIO_SET_PIN(GPIO_PORT_TO_BASE(FM25V02_WP_N_PORT_NUM), GPIO_PIN_MASK(FM25V02_WP_N_PIN)); #endif spi_cs_init(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); }
int rv3049_read_time(rv3049_time_t* time) { uint8_t buf[8]; int i; spix_set_mode(SPI_CONF_DEFAULT_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, SSI_CR0_SPH, 8); SPI_CS_SET(RV3049_CS_PORT_NUM, RV3049_CS_PIN); // Tell the RTC we want to read the clock SPI_WRITE(RV3049_SET_READ_BIT(RV3049_PAGE_ADDR_CLOCK)); SPI_FLUSH(); // Read a null byte here. Not exactly sure why. SPI_READ(buf[0]); // Then actually read the clock for (i=0; i<RV3049_READ_LEN_TIME; i++) { SPI_READ(buf[i]); } SPI_CS_CLR(RV3049_CS_PORT_NUM, RV3049_CS_PIN); // Convert the values time->seconds = BCD_TO_BINARY(buf[0]); time->minutes = BCD_TO_BINARY(buf[1]); time->hours = BCD_TO_BINARY((buf[2])&0x3F); time->days = BCD_TO_BINARY(buf[3]); time->weekday = buf[4]; time->month = buf[5]; time->year = BCD_TO_BINARY(buf[6])+2000; return 0; }
/*---------------------------------------------------------------------------*/ void enc28j60_arch_spi_deselect(void) { SPI_CS_SET(SPI_CS_PORT, SPI_CS_PIN); }
/******************************************************************************* Description: Read all packets from packet outbox via serial SPI interface Arguments: pDev - pointer to the device structure size - amount of data to read Return: rest of data not read or IFX_ERROR *******************************************************************************/ IFX_int32_t serial_read_packet (VINETIC_DEVICE *pDev, IFX_int32_t size) { IFX_int32_t ret = IFX_SUCCESS; IFX_uint8_t packet_length = 0, len = 0; IFX_uint32_t nRev=0; IFX_uint16_t cmd, dummy, pPacketCmd [2] = {0}, pOverflow [MAX_PACKET_WORD] = {0}, *pRead = pOverflow; PACKET *pPacket = NULL; FIFO *pFifo = NULL; IFX_boolean_t bFifo = IFX_FALSE; /* write the packet read command */ cmd = SC_RPOBX; /* set CSQ = LOW */ SPI_CS_SET(IFX_LOW); /* write command and read dummy word */ ret = spi_ll_read_write ((IFX_uint8_t *)&cmd, 2, (IFX_uint8_t *)&dummy, 2); /* read command words and data */ while ((size > 0) && (ret != IFX_ERROR)) { /* read the 2 command words */ ret = spi_ll_read_write (NULL, 0, (IFX_uint8_t *)pPacketCmd, 4); if (ret == IFX_ERROR) break; /* get packet length and packet buffer */ packet_length = pDev->getDataBuf(pDev, pPacketCmd, &pFifo, &pPacket); if (pPacket != NULL) { bFifo = IFX_TRUE; pRead = pPacket->pData; } /* read packet */ for (ret = 0, nRev = 0; nRev < (packet_length * 2); nRev += ret) { if (((packet_length * 2) - nRev) > SPI_MAXBYTES_SIZE) len = SPI_MAXBYTES_SIZE; else len = ((packet_length * 2) - nRev); ret = spi_ll_read_write (NULL, 0, (IFX_uint8_t *)&pRead [nRev/2], len); if (ret == IFX_ERROR) break; } if (ret != IFX_ERROR) { /* remove complete packet size from size */ size -= (2 + packet_length); /* put into fifo */ if (bFifo == IFX_TRUE) { pDev->putDataBuf (pDev, pPacketCmd [0], &pFifo, &pPacket); } } } /* Set CSQ = HIGH */ SPI_CS_SET(IFX_HIGH); /* Recovery time */ IFXOS_DELAYUS (VINETIC_SPI_RECOVERY_TIME); if (ret != IFX_ERROR) ret = size; return ret; }
void fm25v02_sleep(){ spi_set_mode(SSI_CR0_FRF_MOTOROLA, 0, 0, 8); SPI_CS_CLR(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); SPI_WRITE(FM25V02_SLEEP_COMMAND); SPI_CS_SET(FM25V02_CS_N_PORT_NUM, FM25V02_CS_N_PIN); }