/** **************************************************************************************** * @brief Used to transmit the boot image header * @param[in] crc: CRC of the boot image * @param[in] length: Length of the payload in 32-bit words * @param[in] mode: SPI mode used for the transfer * @return Transfer error (0) or transfer OK (1) **************************************************************************************** */ uint32_t send_header(uint32_t length,uint8_t crc,uint32_t mode) { uint32_t spi_read_data; spi_cs_low(); spi_access(0x70); spi_access(0x50); spi_access(0x00); spi_read_data=spi_access(length&0xFF); if(spi_read_data!=SPI_ACK) { spi_cs_high(); return 0; } spi_read_data=spi_access((length>>8)&0xFF); spi_read_data=spi_access(crc); spi_read_data=spi_access(mode); if(spi_read_data!=SPI_ACK) { spi_cs_high(); return 0; } spi_access(0x00); spi_cs_high(); return 1; }
/** **************************************************************************************** * @brief Used to transmit the boot image payload * @param[in] mode: SPI mode used for the transfer * @param[in] length: Length of the payload in 32-bit words * @return Transfer error (0) or transfer OK (1) **************************************************************************************** */ uint8_t send_payload(uint32_t mode,uint32_t length) { uint32_t spi_read_data; uint32_t *ptr; uint32_t i; ptr = (uint32_t*)program_t; spi_cs_high(); /* i=0; do{ i++; }while(i<200); */ spi_cs_low(); for(i=0;i<length;i++) { switch(mode) { case SPI_8BIT: spi_access((*ptr)&0xFF); spi_access((*ptr>>8)&0xFF); spi_access((*ptr>>16)&0xFF); spi_access((*ptr>>24)&0xFF); break; case SPI_16BIT: spi_access((*ptr)&0xFFFF); spi_access((*ptr>>16)&0xFFFF); break; case SPI_32BIT: spi_access(*ptr); break; default: break; }; ptr++; } spi_cs_high(); spi_cs_low(); spi_read_data=spi_access(0x00); if((spi_read_data&0xFF)!=0xAA) { spi_cs_high(); return 0; } spi_read_data=spi_access(0x00); if((spi_read_data&0xFF)!=SPI_ACK) { spi_cs_high(); return 0; } spi_cs_high(); return 1; }
/** **************************************************************************************** * @brief Receive an HCI message over the SPI * @param[in] *msg_ptr: pointer to the position the received data will be stored * @return Message type **************************************************************************************** */ uint16_t spi_receive_hci_msg(uint8_t *msg_ptr) { uint16_t i, size, msg_type; uint8_t * rd_ptr; unsigned char *msg; rd_ptr = msg_ptr+2; // Discard 0x0500; spi_cs_high(); // Close CS spi_cs_low(); // Open CS spi_access(DREADY_ACK); // Write DREADY acknowledge *msg_ptr++ = spi_access(0x00); if (*(msg_ptr-1) == 0x05) // HCI Message { msg_ptr++; // Align 16-bit for (i=0; i<6; i++) { *msg_ptr++ = spi_access(0x00); } *msg_ptr = spi_access(0x00); size = *msg_ptr++; *msg_ptr = spi_access(0x00); size += *msg_ptr++<<8; for (i=0; i<size; i++) { *msg_ptr++ = spi_access(0x00); } msg = malloc(size+8); memcpy(msg,rd_ptr,size+8); EnQueue(&SPIRxQueue, msg, size+8); app_env.size_rx_queue++; msg_type = 1; // GTL Message } else if (*(msg_ptr-1) == FLOW_ON_BYTE) // Flow ON { app_env.slave_on_sleep = SLAVE_ACTIVE; msg_type = 2; // Flow Message } else if (*(msg_ptr-1) == FLOW_OFF_BYTE) // Flow OFF { app_env.slave_on_sleep = SLAVE_NOT_ACTIVE; msg_type = 3; // Flow Message } else { msg_type = 0; // Error } spi_cs_high(); // Close CS return msg_type; }
/** **************************************************************************************** * @brief Fill memory page (up to <SPI Flash page size> bytes) with a given 1-byte value * starting at given address * * @param[in] value: Value used to fill memory * @param[in] address: Starting address * @param[in] size: Size of the area to be filled (should not be larger than SPI Flash page size) * @return error code or success (ERR_OK) **************************************************************************************** */ int8_t spi_flash_page_fill(uint8_t value, uint32_t address, uint16_t size) { int8_t spi_flash_status; uint16_t temp_size = size; if (temp_size > spi_flash_page_size) // check for max page size temp_size = spi_flash_page_size; spi_flash_status = spi_flash_wait_till_ready(); if (spi_flash_status != ERR_OK) return spi_flash_status; // an error has occured spi_flash_status = spi_flash_set_write_enable(); // send [Write Enable] instruction if (spi_flash_status != ERR_OK) return spi_flash_status; // an error has occured spi_set_bitmode(SPI_MODE_32BIT); spi_cs_low(); // pull CS low spi_access( (PAGE_PROGRAM<<24) | address); // Command for page programming spi_set_bitmode(SPI_MODE_8BIT); while(temp_size>0) // Write data bytes { spi_access(value); temp_size--; } spi_cs_high(); // push CS high return spi_flash_wait_till_ready(); }
/** **************************************************************************************** * @brief Read data from a given starting address (up to the end of the flash) * * @param[in] *rd_data_ptr: Points to the position the read data will be stored * @param[in] address: Starting address of data to be read * @param[in] size: Size of the data to be read * * @return Number of read bytes or error code **************************************************************************************** */ int32_t spi_flash_read_data (uint8_t *rd_data_ptr, uint32_t address, uint32_t size) { int8_t spi_flash_status; uint32_t bytes_read, i, temp_size; // check that all bytes to be retrieved are located in valid flash memory address space if (size + address > spi_flash_size) { temp_size = spi_flash_size - address; bytes_read = temp_size; } else { temp_size = size; bytes_read = size; } spi_flash_status = spi_flash_wait_till_ready(); if (spi_flash_status != ERR_OK) return spi_flash_status; // an error has occured spi_set_bitmode(SPI_MODE_32BIT); spi_cs_low(); // pull CS low spi_access( (READ_DATA<<24) | address); // Command for sequencial reading from memory spi_set_bitmode(SPI_MODE_8BIT); for(i=0; i<temp_size; i++) { *rd_data_ptr++ = (uint8_t)spi_access(0x0000); // bare SPI transaction } spi_cs_high(); // push CS high return bytes_read; }
/** * Send data over the spi */ int8_t ker_spi_send_data( uint8_t *msg, uint8_t msg_size, uint8_t calling_id) { HAS_CRITICAL_SECTION; if (s.state == SPI_SYS_IDLE) { return -EINVAL; } if ((s.calling_mod_id != calling_id) || ((s.state != SPI_SYS_WAIT) && (s.state != SPI_SYS_DMA_WAIT))) { return -EBUSY; } // ensure calling app gave us a message if (NULL != msg) { s.usrBuf = s.bufPtr = msg; } else { return -EINVAL; } // need to assert CS pin if (s.flags & SPI_SYS_CS_HIGH_FLAG) { spi_cs_high(s.addr); } else { spi_cs_low(s.addr); } ENTER_CRITICAL_SECTION(); s.len = msg_size; s.state = SPI_SYS_TX; LEAVE_CRITICAL_SECTION(); UART_DBG(a, 0x22, s.calling_mod_id, 0x01, 0x02, SPI_PID); return spi_masterTxData(s.bufPtr, s.len, s.flags); }
/** **************************************************************************************** * @brief SPI 439 Read * @param[in] address: 12 bits register address on 439 * @param[in] data: * * To read one data word from the SPI, 3 transactions are needed. * - First transaction: send command&address * - Second transaction: send dummy 0 * - Third transacation: read returned data * This functions uses POLLING to check if SPI transaction has completed. * * @return data read from the 439 **************************************************************************************** */ uint32_t spi_getword(uint32_t address) // IZP named changed { uint32_t dataRead = 0; spi_cs_low(); uint32_t dataToSend = ((SC14439_MEM_RD<<13) | (address&0x1FFF )); SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend); // write (low part of) dataToSend while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT)); // polling to wait for spi transmission SetWord16(SPI_CLEAR_INT_REG, 0x01); // clear pending flag dataToSend = 0; SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend); // write (low part of) dataToSend while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT)); // polling to wait for spi transmission SetWord16(SPI_CLEAR_INT_REG, 0x01); // clear pending flag SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend); // write (low part of) dataToSend while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT)); // polling to wait for spi transmission SetWord16(SPI_CLEAR_INT_REG, 0x01); // clear pending flag dataRead = GetWord16(SPI_RX_TX_REG0); //read (low part of) data from spi slave spi_cs_high(); return dataRead; // return data read from spi slave }
static void sd_end_command(struct sd_host *host) { /* wait 8 clock cycles as dictated by the specification */ spi_burn_cycles(host, SD_FINISH_CYCLES); /* deselect the card by driving CS high */ spi_cs_high(host); }
void spilcd_cmd(uint8_t cmd) { spi_cs_low(); gpio_set_value(5, 5, 0); spi_xfer(&cmd, NULL, 1); spi_cs_high(); }
void spilcd_dat(uint8_t dat) { spi_cs_low(); gpio_set_value(5, 5, 1); spi_xfer(&dat, NULL, 1); spi_cs_high(); }
/** * Read data from the spi */ int8_t ker_spi_read_data( uint8_t *sharedBuf, uint8_t rx_len, uint8_t rx_cnt, uint8_t calling_id) { HAS_CRITICAL_SECTION; if (s.state == SPI_SYS_IDLE) { // not reserved return -EINVAL; } if ((s.calling_mod_id != calling_id) || ((s.state != SPI_SYS_WAIT) && (s.state != SPI_SYS_DMA_WAIT) && (s.state != SPI_SYS_RX_WAIT))) { return -EBUSY; } // get a handle to users buffer if (rx_len >= MAX_SPI_READ_LEN) { return -EINVAL; } else { s.len = rx_len; } // need to assert CS pin if (s.flags & SPI_SYS_CS_HIGH_FLAG) { spi_cs_high(s.addr); } else { spi_cs_low(s.addr); } // only get/malloc a buffer if we are not currently in a DMA sequence if ((s.flags & SPI_SYS_SHARED_MEM_FLAG)) { if (NULL == sharedBuf) { return -EINVAL; } else { s.cnt = rx_cnt; s.bufPtr = sharedBuf; if (!(s.state == SPI_SYS_DMA_WAIT)) { s.usrBuf = sharedBuf; } } } else { // ignore value of sharedBuf if (NULL == (s.bufPtr = s.usrBuf = ker_malloc(s.len, SPI_PID))) { return -ENOMEM; } else { s.cnt = 1; } } ENTER_CRITICAL_SECTION(); s.state = SPI_SYS_RX; LEAVE_CRITICAL_SECTION(); return spi_masterRxData(s.usrBuf, s.len, s.flags); }
static void w5200_write_register(uint16_t addr, uint8_t data) { spi_cs_low(); spi_transfer(high_byte(addr)); spi_transfer(low_byte(addr)); spi_transfer(0x80); spi_transfer(0x01); spi_transfer(data); spi_cs_high(); }
/** **************************************************************************************** * @brief Send an HCI message over the SPI * @param[in] size: size of data to send in bytes * @param[in] *msg_ptr: pointer to the first byte to be sent **************************************************************************************** */ void spi_send_hci_msg(uint16_t size, uint8_t *msg_ptr) { uint16_t i; NVIC_DisableIRQ(GPIO0_IRQn); while(GetBits16(SPI_DATA_REG,1<<SPI_DREADY_PIN)==1); // Polling DREADY to detect if data is being received spi_cs_high(); // Close CS spi_cs_low(); // Open CS spi_access(0x05); for (i=0; i<size; i++) { spi_access(*msg_ptr++); } spi_cs_high(); // Close CS NVIC_EnableIRQ(GPIO0_IRQn); }
void RF24::csn(int mode) { // Minimum ideal SPI bus speed is 2x data rate // If we assume 2Mbs data rate and 16Mhz clock, a // divider of 4 is the minimum we want. // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz //TODO: change speed if necessary if (mode) spi_cs_high(); else spi_cs_low(); }
/* Private register IO functions */ static uint8_t w5200_read_register(uint16_t addr){ uint8_t data; spi_cs_low(); spi_transfer(high_byte(addr)); spi_transfer(low_byte(addr)); spi_transfer(0x00); spi_transfer(0x01); data = spi_transfer(0); spi_cs_high(); return data; }
/** **************************************************************************************** * @brief Start or Restart the 439 SPI to get it ready for fetching Audio Data * * @return void **************************************************************************************** */ void spi_439_codec_restart(void) { /* disable interrupts, and use 16 bits transfers.. */ SetBits16(SPI_CTRL_REG, SPI_MINT, SPI_MINT_DISABLE); SetBits16(SPI_CTRL_REG, SPI_WORD, SPI_MODE_16BIT ); spi_cs_high(); SetWord439(SC14439_DMA0_CTRL_REG,0x0E2C); // Disable, SYNC_SEL=0, DREQ_LEVEL=1,CIRUCLAR=1., AINC=10,BINC=00 DREQ_MODE=1, RSRV, IND=1, DIR=1, RSRVD, DMA_ON=0 = 0.1110.0010.1100 SetWord439(SC14439_DMA0_A_IDX_REG,20); SetWord439(SC14439_DMA0_CTRL_REG,0x062D); // Enable, SYNC_SEL=0, DREQ_LEVEL=0,CIRUCLAR=1., AINC=10,BINC=00 DREQ_MODE=1, RSRV, IND=1, DIR=1, RSRVD, DMA_ON=1 = 0.0110.0010.1101 /* Now enable interupts, use 32 bits and pull enable low */ SetBits16(SPI_CTRL_REG, SPI_MINT, SPI_MINT_ENABLE); SetBits16(SPI_CTRL_REG, SPI_WORD, SPI_MODE_32BIT ); spi_cs_low(); /* This enables the SPI. It can stay low for all Audio SPI transactions */ }
/** **************************************************************************************** * @brief Get JEDEC ID * @return JEDEC ID **************************************************************************************** */ int32_t spi_read_flash_jedec_id(void) { int8_t spi_flash_status; uint32_t jedec_id; spi_flash_status = spi_flash_wait_till_ready(); if (spi_flash_status != ERR_OK) return spi_flash_status; // an error has occured spi_set_bitmode(SPI_MODE_8BIT); spi_cs_low(); // pull CS low spi_access(JEDEC_ID); // SPI accsss to send [Read Unique ID] command jedec_id = spi_access(0x0000) << 16; // SPI accsss to get the JEDEC Manufacturer ID jedec_id |= spi_access(0x0000) << 8; // SPI accsss to get device information byte 1 jedec_id |= spi_access(0x0000); // SPI accsss to get device information byte 2 spi_cs_high(); // push CS high return jedec_id; }
/** **************************************************************************************** * @brief Get Manufacturer / Device ID * @return Manufacturer/Device ID (0 in case of time-out) **************************************************************************************** */ int16_t spi_read_flash_memory_man_and_dev_id(void) { int8_t spi_flash_status; uint16_t idWord = 0; spi_flash_status = spi_flash_wait_till_ready(); if (spi_flash_status == ERR_OK) { spi_set_bitmode(SPI_MODE_16BIT); spi_cs_low(); // pull CS low spi_access(MAN_DEV_ID<<8); // SPI transaction to send command spi_access(0x0000); // dummy SPI transaction to send (A23-A0) idWord = spi_access(0x0000); // SPI transaction to read Manufacturer Id, Device ID spi_cs_high(); // push CS high } return idWord; }
/** **************************************************************************************** * @brief SPI 439 Write * @param[in] address: 12 bits address on 439 * @param[in] data: 16 bits value for the register * * To write one data word to 439 with the SPI, 2 transactions are needed. * - First transaction: send command&address * - Second transaction: write data * This functions uses POLLING to check if SPI transaction has completed. * * @return data read **************************************************************************************** */ void spi_setword(uint32_t address, uint32_t data) // IZP named changed { spi_cs_low(); uint32_t dataToSend = ((SC14439_MEM_WR<<13) | (address&0x1FFF )); SetWord16(SPI_RX_TX_REG0, (uint16_t)dataToSend); // write address while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT)); // polling to wait for spi transmission SetWord16(SPI_CLEAR_INT_REG, 0x01); // clear pending flag SetWord16(SPI_RX_TX_REG0, (uint16_t)data); // write (low part of) dataToSend while (!GetBits16(SPI_CTRL_REG, SPI_INT_BIT)); // polling to wait for spi transmission SetWord16(SPI_CLEAR_INT_REG, 0x01); // clear pending flag spi_cs_high(); }
/** **************************************************************************************** * @brief Get Unique ID Number * @return Unique ID Number (0 in case of time-out) **************************************************************************************** */ uint64_t spi_read_flash_unique_id(void) { int8_t spi_flash_status; uint64_t unique_id = 0; spi_flash_status = spi_flash_wait_till_ready(); if (spi_flash_status == ERR_OK) { spi_set_bitmode(SPI_MODE_8BIT); spi_cs_low(); // pull CS low spi_access(READ_UNIQUE_ID); // SPI access to send [Read Unique ID] command spi_set_bitmode(SPI_MODE_32BIT); // dummy transaction for the 4 dummy bytes spi_access(0x0000); // dummy bare SPI transaction unique_id = ((uint64_t)spi_access(0x0000) << 32); // SPI access to get the high part of unique id unique_id |= spi_access(0x0000); // bare SPI access to get the high part of unique id spi_cs_high(); // push CS high } return unique_id; }