void spi_sendToDev(packet_t *pkt) { //cli(); uint8_t len; uint8_t flag = 0xAA; if(pkt) { spi_select_device(SPI_USB, &SPI_DEVICE_USB); SPIC.DATA = flag; while(!spi_is_rx_full(SPI_USB)); spi_write_packet(SPI_USB, &(pkt->len), 1); spi_write_packet(SPI_USB, &(pkt->task), 1); spi_write_packet(SPI_USB, &(pkt->subTask), 1); spi_write_packet(SPI_USB, pkt->buf, pkt->len); spi_deselect_device(SPI_USB, &SPI_DEVICE_USB); } else { LED_On(LED6_GPIO); } sei(); }
// reg: 5 bit memory map address (LSB first) // Note: Executable in power down or standby modes only void nrf24l01_write_register(uint8_t reg, uint8_t writeData) { spi_select_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); uint8_t data[2] = {NRF24L01_W_REGISTER | (NRF24L01_REGISTER_MASK & reg), writeData }; spi_write_packet(&CONF_NRF24L01_SPI, data, 2); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); }
/** * Send an instruction to the nRF24L01. * \param instruction The instruction to send (see the bottom of nRF24L01.h) * \param data An array of argument data to the instruction. If len is 0, then this may be NULL. * \param buffer An array for the instruction's return data. This can be NULL if the instruction has no output. * \param len The length of the data and buffer arrays. */ static void send_instruction(uint8_t instruction, uint8_t* data, uint8_t* buffer, uint8_t len) { spi_select_device(&SPID, &spi_device_conf); // send the instruction spi_write_packet (&SPID, &instruction, 1); // pass in args if (len > 0) { if (buffer == NULL) { spi_write_packet (&SPID, data, len); } else { for (int i = 0; i < len; i++) { spi_write_packet (&SPID, &(data[i]), 1); spi_read_packet (&SPID, &(buffer[i]), 1); } } } // resynch SPI spi_deselect_device(&SPID, &spi_device_conf); }
uint8_t* nrf24l01_read_array_register(uint8_t reg, uint8_t* readData, uint8_t dataLen) { spi_select_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); spi_write_single_packet(&CONF_NRF24L01_SPI, NRF24L01_R_REGISTER | (NRF24L01_REGISTER_MASK & reg)); spi_read_packet(&CONF_NRF24L01_SPI, readData, dataLen); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); return readData; }
void spi_polled(void) { cli(); uint8_t display = 0x88; packet_t *packet = TM_newPacket(); if(!(packet)) { LED_Toggle(LED5_GPIO); sei(); return; } spi_select_device(SPI_USB, &SPI_DEVICE_USB); uint8_t len = 0; spi_write_packet(SPI_USB, &display, 1); _delay_us(10); spi_read_packet(SPI_USB, &(packet->len), 1); _delay_us(10); len= packet->len; if(len == 0 || len >= 0x88) { spi_deselect_device(SPI_USB, &SPI_DEVICE_USB); sei(); // alarm_new(5, "Received a SPI Packet with no Length"); LED_Toggle(LED4_GPIO); TM_freePacket(packet); return; } spi_read_packet(SPI_USB, &(packet->task), 1); _delay_us(10); spi_read_packet(SPI_USB, &(packet->subTask), 1); packet->ptr = packet->buf; _delay_us(10); spi_read_packet(SPI_USB, packet->ptr, len); sei(); packet->dir = from_device; spi_deselect_device(SPI_USB, &SPI_DEVICE_USB); }
// reg: 5 bit memory map address (LSB first) uint8_t nrf24l01_read_register(uint8_t reg) { spi_select_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); spi_write_single_packet(&CONF_NRF24L01_SPI, NRF24L01_R_REGISTER | (NRF24L01_REGISTER_MASK & reg)); uint8_t readData; spi_read_packet(&CONF_NRF24L01_SPI, &readData, 1); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); return readData; }
// Initialize Pin and SPI like specified into config file void nrf24l01_init() { // Init SPI pins ioport_set_pin_dir(CONF_NRF24L01_SS_PIN, IOPORT_DIR_INPUT); ioport_set_pin_mode(CONF_NRF24L01_SS_PIN, IOPORT_MODE_PULLUP); ioport_set_pin_dir(CONF_NRF24L01_MOSI_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_mode(CONF_NRF24L01_MOSI_PIN, IOPORT_MODE_PULLUP); ioport_set_pin_high(CONF_NRF24L01_MOSI_PIN); ioport_set_pin_dir(CONF_NRF24L01_MISO_PIN, IOPORT_DIR_INPUT); ioport_set_pin_dir(CONF_NRF24L01_SCK_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_high(CONF_NRF24L01_SCK_PIN); // Init nrf24l01 pins ioport_set_pin_dir(CONF_NRF24L01_CE_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_dir(CONF_NRF24L01_CSn_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_dir(CONF_NRF24L01_IRQ_PIN, IOPORT_DIR_INPUT); ioport_set_pin_low(CONF_NRF24L01_CE_PIN); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); spi_master_init(&CONF_NRF24L01_SPI); spi_master_setup_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf, SPI_MODE_0, CONF_NRF24L01_CLOCK_SPEED, 0); spi_enable(&CONF_NRF24L01_SPI); // Wait nrf24l01 power on reset delay_ms(Tpor); nrf24l01_power_off(); // Reset registers to default state nrf24l01_write_register(NRF24L01_CONFIG_REG, NRF24L01_CONFIG_REG_DEF); nrf24l01_write_register(NRF24L01_STATUS_REG, NRF24L01_STATUS_REG_DEF); // TODO: reset all registers // Config parameters sets in CONF_NRF24L01 nrf24l01_set_power_amplifier(CONF_NRF24L01_PA); nrf24l01_set_data_rate(CONF_NRF24L01_DATA_RATE); nrf24l01_set_crc(CONF_NRF24L01_CRC); nrf24l01_set_addr_len(CONF_NRF24L01_ADDR_LEN); uint8_t nrf24l01_rx_addr[5] = { CONF_NRF24L01_RX_ADDR }; uint8_t nrf24l01_tx_addr[5] = { CONF_NRF24L01_TX_ADDR }; nrf24l01_set_rx_addr(nrf24l01_rx_addr); nrf24l01_set_tx_addr(nrf24l01_tx_addr); nrf24l01_write_register(NRF24L01_RF_CH_REG, CONF_NRF24L01_RF_CHANNEL); nrf24l01_write_register(NRF24L01_RX_PW_P0_REG, CONF_NRF24L01_PAYLOAD); nrf24l01_write_register(NRF24L01_RX_PW_P1_REG, CONF_NRF24L01_PAYLOAD); // Power-up (Power Down -> Standby-I) uint8_t configReg = nrf24l01_read_register(NRF24L01_CONFIG_REG); nrf24l01_write_register(NRF24L01_CONFIG_REG, configReg | NRF24L01_PWR_UP_BM); delay_us(Tpd2stby); }
char CCStrobe(char addr) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr); spi_read_single(&SPIC, &stat); spi_deselect_device(&SPIC, &spi_device_conf); return stat; }
/** * \brief Setup a SPI device. * * The returned device descriptor structure must be passed to the driver * whenever that device should be used as current slave device. * * \param spi Base address of the SPI instance. * \param device Pointer to SPI device struct that should be initialized. * \param flags SPI configuration flags. Common flags for all * implementations are the SPI modes SPI_MODE_0 ... * SPI_MODE_3. * \param baud_rate Baud rate for communication with slave device in Hz. * \param sel_id Board specific seclet id */ void spi_master_setup_device(SPI_t *spi, struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id) { spi_deselect_device(spi, device); if(spi_xmega_set_baud_div(spi, baud_rate,sysclk_get_cpu_hz())<0) { //TODO Assert impossible baudrate } spi->CTRL|=(flags<<SPI_MODE_gp)&SPI_MODE_gm; }
/** * Retrieve the status register. */ static uint8_t get_status(void) { uint8_t status = 0xFF; spi_select_device(&SPID, &spi_device_conf); spi_write_packet (&SPID, &status, 1); spi_read_packet (&SPID, &status, 1); spi_deselect_device(&SPID, &spi_device_conf); return status; }
uint8_t AT42QT1110_send_cmd(uint8_t cmd) { uint8_t data; spi_select_device(SPI_TOUCH, &spi_device_touch); spi_write_single(SPI_TOUCH, cmd); data = AT42QT1110_spi_read_timeout(&data, 100); spi_deselect_device(SPI_TOUCH, &spi_device_touch); return data; }
void ENC28J60_WriteBuffer(uint16_t len, uint8_t* data) { status_code_t ret = STATUS_OK; spi_select_device(avr32SPI, &spiDevice); spi_write_single(avr32SPI, ENC28J60_WRITE_BUF_MEM); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } ret = spi_write_packet(avr32SPI, data, len); spi_deselect_device(avr32SPI, &spiDevice); }
char CCWriteBurst(char addr, const char* dataPtr, char size) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr|0x40); spi_read_single(&SPIC, &stat); spi_write_packet(&SPIC, *dataPtr, size); spi_deselect_device(&SPIC, &spi_device_conf); return stat; }
void AT42QT1110_send_data(uint8_t* data, uint8_t length) { uint8_t i; spi_select_device(SPI_TOUCH, &spi_device_touch); for (i=0; i<length; i++) { delay_us(150); spi_write_single(SPI_TOUCH, data[i]); } spi_deselect_device(SPI_TOUCH, &spi_device_touch); return; }
uint8_t CS4270_read_data(void) { uint8_t data; spi_select_device(SPI_CODEC, &spi_device_codec); spi_write_single(SPI_CODEC, CS4270_ADDRESS_READ); spi_read_single(SPI_CODEC, &data); spi_deselect_device(SPI_CODEC, &spi_device_codec); return data; }
char CCRead(char addr, char* data) { char stat; spi_select_device(&SPIC, &spi_device_conf); while(PORTC.IN&PIN6_bm==PIN6_bm); //Wait for MISO to go low spi_write_single(&SPIC, addr|0x80); spi_read_single(&SPIC, &stat) spi_write_single(&SPIC, CONFIG_SPI_MASTER_DUMMY); spi_read_single(&SPIC, data); spi_deselect_device(&SPIC, &spi_device_conf); return stat; };
/** * Set a register in the radio * \param reg The register value defined in nRF24L01.h (e.g. CONFIG, EN_AA, &c.). * \param value The value to write to the given register (the whole register is overwritten). * \return The status register. */ static uint8_t set_register(radio_register_t reg, uint8_t* value, uint8_t len) { uint8_t status; uint8_t byte = W_REGISTER | (REGISTER_MASK & reg); spi_select_device(&SPID, &spi_device_conf); spi_write_packet (&SPID, &byte, 1); spi_read_packet (&SPID, &status, 1); spi_write_packet (&SPID, value, len); spi_deselect_device(&SPID, &spi_device_conf); return status; }
uint8_t ENC28J60_ReadOp(uint8_t op, uint8_t address) { uint8_t cmd; uint8_t data = 0; spi_select_device(avr32SPI, &spiDevice); cmd = op | GET_REGISTERADDRESS(address); spi_write_packet(avr32SPI, &cmd, 1); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } spi_read_packet(avr32SPI, &data, 1); spi_deselect_device(avr32SPI, &spiDevice); return data; }
// Reads payload bytes into data array void nrf24l01_receive_data(uint8_t* data) { spi_select_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); spi_write_single_packet(&CONF_NRF24L01_SPI, NRF24L01_R_RX_PAYLOAD); spi_read_packet(&CONF_NRF24L01_SPI, data, CONF_NRF24L01_PAYLOAD); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); // NVI: per product spec, p 67, note c: // "The RX_DR IRQ is asserted by a new packet arrival event. The procedure // for handling this interrupt should be: 1) read payload through SPI, // 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more // payloads available in RX FIFO, 4) if there are more data in RX FIFO, // repeat from step 1)." // So if we're going to clear RX_DR here, we need to check the RX FIFO // in the dataReady() function nrf24l01_write_register(NRF24L01_STATUS_REG, NRF24L01_RX_DR_BM); // Reset status register }
void RF230frameWrite(uint8_t *frame_wr, uint8_t len) { report_packet(frame_wr, len); cli(); /* Start transmission */ spi_select_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); spi_write_once(SPI_ZIGBEE, RF230_SPI_FRAME_WRITE); spi_write_once(SPI_ZIGBEE, len); spi_write_packet(SPI_ZIGBEE, frame_wr, len); spi_deselect_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); // end of transmissions sei(); }// end RF230frameWrite
static sint8 spi_rw(uint8* pu8Mosi, uint8* pu8Miso, uint16 u16Sz) { struct spi_device spi_device_conf; spi_device_conf.id = CONF_WIFI_M2M_SPI_CS_PIN; uint8 u8Dummy = 0; uint8 u8SkipMosi = 0, u8SkipMiso = 0; uint16_t txd_data = 0; uint16_t rxd_data = 0; if (!pu8Mosi) { pu8Mosi = &u8Dummy; u8SkipMosi = 1; } else if(!pu8Miso) { pu8Miso = &u8Dummy; u8SkipMiso = 1; } else { return M2M_ERR_BUS_FAIL; } spi_select_device(CONF_WIFI_M2M_SPI_MODULE, &spi_device_conf); while (u16Sz) { txd_data = *pu8Mosi; /* Write one byte */ spi_write_packet(CONF_WIFI_M2M_SPI_MODULE, (uint8_t*)(&txd_data), 1); /* Read SPI master data register. */ spi_read_single(CONF_WIFI_M2M_SPI_MODULE, (uint8_t*)(&rxd_data)); *pu8Miso = rxd_data; u16Sz--; if (!u8SkipMiso) pu8Miso++; if (!u8SkipMosi) pu8Mosi++; } spi_deselect_device(CONF_WIFI_M2M_SPI_MODULE, &spi_device_conf); return M2M_SUCCESS; }
void AT42QT1110_get_data(uint8_t cmd, uint8_t* data, uint8_t length) { uint8_t idle; uint8_t i; spi_select_device(SPI_TOUCH, &spi_device_touch); idle = AT42QT1110_send_cmd(cmd); if (idle != 0x55) return; for (i=0; i<length; i++) { delay_us(150); spi_write_single(SPI_TOUCH, 0x00); AT42QT1110_spi_read_timeout(data, 100); } spi_deselect_device(SPI_TOUCH, &spi_device_touch); return; }
void RF230registerWrite(uint8_t address, uint8_t data) { uint8_t temp_address; temp_address = address; temp_address |= RF230_SPI_WRITE; cli(); /* Start transmission */ spi_select_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); /* Send Address */ spi_write_once(SPI_ZIGBEE, temp_address); /* Send New Register value */ spi_write_once(SPI_ZIGBEE, data); /* End Transmission */ spi_deselect_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); // end of transmissions sei(); }
void spi_sensor_init(void) { uint8_t data_buffer[3] = {0x0, 0x0, 0x0}; spi_init_pins(); spi_master_init(&SPIC); spi_master_setup_device(&SPIC, &SPI_ADC, SPI_MODE_3, 500000, 0); spi_enable(&SPIC); spi_select_device(&SPIC, &SPI_ADC); spi_write_packet(&SPIC, resetdata, 5); //clock reg data_buffer[0] = 0x20; spi_write_packet(&SPIC, data_buffer, 1); //data_buffer[0] = 0x00; data_buffer[0] = clockreg; spi_write_packet(&SPIC, data_buffer, 1); //setup reg data_buffer[0] = 0x10; spi_write_packet(&SPIC, data_buffer, 1); //data_buffer[0] = 0x04; data_buffer[0] = setupreg; spi_write_packet(&SPIC, data_buffer, 1); //offset reg data_buffer[0] = 0x60; spi_write_packet(&SPIC, data_buffer, 1); data_buffer[0] = 0x18; data_buffer[1] = 0x3A; data_buffer[2] = 0x00; spi_write_packet(&SPIC, data_buffer, 3); //gain reg data_buffer[0] = 0x70; spi_write_packet(&SPIC, data_buffer, 1); data_buffer[0] = 0x89; data_buffer[1] = 0x78; data_buffer[2] = 0xD7; spi_write_packet(&SPIC, data_buffer, 3); spi_deselect_device(&SPIC, &SPI_ADC); }
void ENC28J60_WriteOp(uint8_t op, uint8_t address, uint8_t data) { uint8_t cmd; spi_select_device(avr32SPI, &spiDevice); cmd = op | GET_REGISTERADDRESS(address); spi_write_single(avr32SPI, cmd); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } spi_write_single(avr32SPI, data); for(;;) { if(spi_is_tx_ready(avr32SPI)) break; } spi_deselect_device(avr32SPI, &spiDevice); }
uint8_t RF230FrameBufferRead(uint8_t *frame_rx) { uint8_t dummy = 0x00; uint8_t len, index = 0, length; cli(); /* Start transmission */ spi_select_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); spi_write_once(SPI_ZIGBEE, RF230_SPI_SRAM_READ); /* Wait for transmission complete */ len = spi_read_once(SPI_ZIGBEE); length = len; spi_read_packet(SPI_ZIGBEE, frame_rx, len); spi_deselect_device(SPI_ZIGBEE, &SPI_DEVICE_ZIGBEE); // end of transmissions //report_packet(frame_rx, len); sei(); return length; }
/** * Retrieve a register value from the radio. * \param reg The register value defined in nRF24L01.h (e.g. CONFIG, EN_AA, &c.). * \param buffer A contiguous memory block into which the register contents will be copied. If the buffer is too long for the * register contents, then the remaining bytes will be overwritten with 0xFF. * \param len The length of the buffer. */ static uint8_t get_register(radio_register_t reg, uint8_t* buffer, uint8_t len) { uint8_t status, i; uint8_t byte = R_REGISTER | (REGISTER_MASK & reg); for (i = 0; i < len; i++) { // If the buffer is too long for the register results, then the radio will interpret the extra bytes as instructions. // To remove the risk, we set the buffer elements to NOP instructions. buffer[i] = 0xFF; } spi_select_device(&SPID, &spi_device_conf); spi_write_packet (&SPID, &byte, 1); spi_read_packet (&SPID, &status, 1); spi_read_packet (&SPID, buffer, len); spi_deselect_device(&SPID, &spi_device_conf); return status; }
static bool spi_at45dbx_mem_check(void) { // Select the DF memory to check. spi_select_device(SPI_EXAMPLE,&SPI_DEVICE_EXAMPLE); // Send the Status Register Read command following by a dummy data. spi_write_packet(SPI_EXAMPLE, data, 1); // Receive status. spi_read_packet(SPI_EXAMPLE, data,1); // Extract the status. status = data[0]; // Deselect the checked DF memory. spi_deselect_device(SPI_EXAMPLE,&SPI_DEVICE_EXAMPLE); // Unexpected device density value. if ((status & AT45DBX_MSK_DENSITY) < AT45DBX_DENSITY) return false; else return true; }
void CS4270_send_data(uint8_t* data, uint8_t length, uint8_t start_reg) { uint8_t i; spi_select_device(SPI_CODEC, &spi_device_codec); spi_write_single(SPI_CODEC, CS4270_ADDRESS_WRITE); if (length > 1) { //If writing to multiple registers, need incr bit spi_write_single(SPI_CODEC, start_reg | (1 << 7)); } else { spi_write_single(SPI_CODEC, start_reg); } for (i=0; i<length; i++) { spi_write_single(SPI_CODEC, data[i]); } spi_deselect_device(SPI_CODEC, &spi_device_codec); }
// Sends a data package to the default address. Be sure to send the correct // amount of bytes as configured as payload on the receiver. void nrf24l01_send_data(uint8_t* value) { // Wait until last packet is sent if in TX mode while (PTX) { uint8_t status = nrf24l01_read_register(NRF24L01_STATUS_REG); // Packet transmitted or Max retransmission if((status & (NRF24L01_TX_DS_BM | NRF24L01_MAX_RT_BM))){ PTX = 0; break; } } nrf24l01_write_register(NRF24L01_STATUS_REG, NRF24L01_TX_DS_BM | NRF24L01_MAX_RT_BM); ioport_set_pin_low(CONF_NRF24L01_CE_PIN); nrf24l01_primary_tx(); spi_select_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); spi_write_single_packet(&CONF_NRF24L01_SPI, NRF24L01_W_TX_PAYLOAD); spi_write_packet(&CONF_NRF24L01_SPI, value, CONF_NRF24L01_PAYLOAD); spi_deselect_device(&CONF_NRF24L01_SPI, &nrf24l01_spi_device_conf); ioport_set_pin_high(CONF_NRF24L01_CE_PIN); // Start transmission delay_us(Thce); delay_us(Tstby2a); }