/** * \brief read data through DesignWare SPI * \param[in] spi_info_ptr spi information structure pointer * \param[out] data data that need to read (data must be char type) * \param[in] len data count need to read * \retval >=0 data have been read * \retval E_PAR arguments passed was wrong * \retval E_OBJ spi has something error, nothing can be done * \retval E_CLSED spi was closed, not available for control * \retval <0 other error code not defined here */ int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len) { int32_t ercd = E_OK; DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); /* START ERROR CHECK */ VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); DW_SPI_CHECK_EXP(spi_info_ptr->status & DEV_ENABLED, E_SYS); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); DW_SPI_CHECK_EXP(data!=NULL, E_PAR); DW_SPI_CHECK_EXP(len>0, E_PAR); /* END OF ERROR CHECK */ DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); DEV_SPI_TRANSFER spi_xfer; /* Master and Slave transmit */ DEV_SPI_XFER_SET_TXBUF(&spi_xfer, NULL, len, 0); DEV_SPI_XFER_SET_RXBUF(&spi_xfer, data, 0, len); DEV_SPI_XFER_SET_NEXT(&spi_xfer, NULL); /* Check transfer align */ DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(&spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); dw_spi_init_transfer(spi_ctrl_ptr, &spi_xfer, spi_info_ptr->dfs); ercd = dw_spi_poll_transfer(spi_info_ptr); error_exit: return ercd; }
/* need test */ void pmrf_txpkt_frame_write(uint8_t *frame, int16_t hdr_len, int16_t frame_len) { uint8_t msg[frame_len + 2 + 2]; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; uint8_t i = 0; msg[0] = (uint8_t)(((MRF24J40_TXNFIFO >> 3) & 0x7F) | 0x80); msg[1] = (uint8_t)(((MRF24J40_TXNFIFO << 5) & 0xE0) | (1 << 4)); msg[2] = (uint8_t)hdr_len; msg[3] = (uint8_t)frame_len; for (i = 0; i < frame_len; i++) { msg[i + 4] = *frame; frame++; } DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, frame_len + 2 + 2); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, NULL, frame_len + 2 + 2, 0); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif }
void pmrf_txfifo_write(uint16_t address, uint8_t *data, uint8_t hdr_len, uint8_t len) { uint8_t msg[len + 4]; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; uint8_t i = 0; msg[0] = (uint8_t)(((address >> 3) & 0x7F) | 0x80); msg[1] = (uint8_t)(((address << 5) & 0xE0) | (1 << 4)); msg[2] = hdr_len; msg[3] = len; for (i = 0; i < len; i++) { msg[i + 4] = *(data + i); } DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, len + 4); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, NULL, len + 4, 0); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif }
/* need test */ void pmrf_set_key(uint16_t addr, uint8_t *key) { uint8_t msg[16 + 2]; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; uint8_t i; msg[0] = (uint8_t)(((addr >> 3) & 0x7F) | 0x80); msg[1] = (uint8_t)(((addr << 5) & 0xE0) | (1 << 4)); for (i = 0; i < 16; i++) { msg[i + 2] = key[0]; } DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, 18); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, NULL, 18, 0); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif }
void pmrf_write_short_ctrl_reg(uint8_t addr, uint8_t value) { DEV_SPI_TRANSFER pmrf_xfer; uint8_t msg[3]; uint32_t cpu_status; msg[0] = (((addr << 1) & 0x7E) | 1); msg[1] = value; msg[2] = 0x0; /* have to write 1 more byte, why ?*/ DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, 3); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, NULL, 3, 0); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif }
uint8_t pmrf_read_short_ctrl_reg(uint8_t addr) { uint8_t msg; uint8_t ret_val; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; msg = (((addr << 1) & 0x7E) | 0); DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, &msg, 0, 1); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, &ret_val, 1, 1); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif return ret_val; }
uint8_t pmrf_read_long_ctrl_reg(uint16_t addr) { uint8_t msg[2]; uint8_t ret_val; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; msg[0] = (uint8_t)(((addr >> 3) & 0x7F) | 0x80); msg[1] = (uint8_t)((addr << 5) & 0xE0); DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, 2); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, &ret_val, 2, 1); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif return ret_val; }
/* need test */ void pmrf_rxpkt_intcb_frame_read(uint8_t *buf, uint8_t length) { uint8_t msg[length]; DEV_SPI_TRANSFER pmrf_xfer; uint32_t cpu_status; msg[0] = (uint8_t)((((MRF24J40_RXFIFO + 1) >> 3) & 0x7F) | 0x80); msg[1] = (uint8_t)(((MRF24J40_RXFIFO + 1) << 5) & 0xE0); DEV_SPI_XFER_SET_TXBUF(&pmrf_xfer, msg, 0, 2); DEV_SPI_XFER_SET_RXBUF(&pmrf_xfer, buf, 2, length); DEV_SPI_XFER_SET_NEXT(&pmrf_xfer, NULL); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_status = cpu_lock_save(); #endif pmrf_spi_ptr->spi_control(SPI_CMD_MST_SEL_DEV, CONV2VOID(cs_line)); pmrf_spi_ptr->spi_control(SPI_CMD_TRANSFER_POLLING, CONV2VOID(&pmrf_xfer)); pmrf_spi_ptr->spi_control(SPI_CMD_MST_DSEL_DEV, CONV2VOID(cs_line)); #ifdef EMSK_PMRF_0_SPI_CPULOCK_ENABLE cpu_unlock_restore(cpu_status); #endif }
/** * \brief control spi by ctrl command * \param[in] spi_obj spi object pointer * \param[in] ctrl_cmd control command code to do specific spi work * \param[in,out] param parameters used to control spi or return something * \retval E_OK Control device successfully * \retval E_CLSED Device is not opened * \retval E_OBJ Device object is not valid or not exists * \retval E_PAR Parameter is not valid for current control command * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled * \retval E_CTX Control device failed, due to different reasons like in transfer state * \retval E_NOSPT Control command is not supported or not valid */ int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param) { int32_t ercd = E_OK; DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); /* START ERROR CHECK */ VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); /* END OF ERROR CHECK */ uint32_t val32; /** to receive unsigned int value */ DEV_BUFFER *devbuf; DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); DEV_SPI_TRANSFER *spi_xfer = &(spi_info_ptr->xfer); /* check whether current device is disabled */ if ((spi_info_ptr->status & DEV_ENABLED) == 0) { /** When device is disabled, * only SPI_CMD_ENA_DEV, SPI_CMD_DIS_DEV, SPI_CMD_GET_STATUS, SPI_CMD_RESET * are available, other commands will return E_SYS */ if ((ctrl_cmd != SPI_CMD_ENA_DEV) && \ (ctrl_cmd != SPI_CMD_DIS_DEV) && \ (ctrl_cmd != SPI_CMD_GET_STATUS) && \ (ctrl_cmd != SPI_CMD_RESET) ) { return E_SYS; } } switch (ctrl_cmd) { /* Commmon commands for both master and slave mode */ case SPI_CMD_GET_STATUS: DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); *((int32_t *)param) = spi_info_ptr->status; break; case SPI_CMD_SET_CLK_MODE: DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); val32 = (uint32_t)param; DW_SPI_CHECK_EXP((val32>=SPI_CPOL_0_CPHA_0) && (val32<=SPI_CPOL_1_CPHA_1), E_PAR); if (dw_spi_set_clockmode(spi_reg_ptr, val32) == 0) { spi_info_ptr->clk_mode = val32; } else { ercd = E_SYS; } break; case SPI_CMD_ENA_DEV: dw_spi_enable_device(spi_info_ptr); break; case SPI_CMD_DIS_DEV: dw_spi_disable_device(spi_info_ptr); break; case SPI_CMD_RESET: dw_spi_reset_device(spi_info_ptr); break; case SPI_CMD_FLUSH_TX: DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); dw_spi_flush_tx(spi_reg_ptr); break; case SPI_CMD_FLUSH_RX: DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); dw_spi_flush_rx(spi_reg_ptr); break; case SPI_CMD_SET_DFS: DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); val32 = (uint32_t)param; DW_SPI_CHECK_EXP(val32>0, E_PAR); if (dw_spi_set_dfs(spi_reg_ptr, val32) == 0) { spi_info_ptr->dfs = val32; } else { ercd = E_SYS; } break; case SPI_CMD_SET_DUMMY_DATA: val32 = (uint32_t)param; spi_info_ptr->dummy = val32; break; case SPI_CMD_GET_RXAVAIL: /* Notice in bytes unit */ DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); *((int32_t *)param) = dw_spi_get_rxavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); break; case SPI_CMD_GET_TXAVAIL: /* Notice in bytes unit */ DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); *((int32_t *)param) = dw_spi_get_txavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); break; case SPI_CMD_SET_TXCB: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); spi_info_ptr->spi_cbs.tx_cb = param; break; case SPI_CMD_SET_RXCB: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); spi_info_ptr->spi_cbs.rx_cb = param; break; case SPI_CMD_SET_XFERCB: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); spi_info_ptr->spi_cbs.xfer_cb = param; break; case SPI_CMD_SET_ERRCB: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); spi_info_ptr->spi_cbs.err_cb = param; break; case SPI_CMD_ABORT_TX: ercd = dw_spi_abort_tx(spi_obj); break; case SPI_CMD_ABORT_RX: ercd = dw_spi_abort_rx(spi_obj); break; case SPI_CMD_ABORT_XFER: ercd = dw_spi_abort_xfer(spi_obj); break; case SPI_CMD_SET_TXINT: val32 = (uint32_t)param; if (val32 == 0) { ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); } else { ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_SND); } break; case SPI_CMD_SET_RXINT: val32 = (uint32_t)param; if (val32 == 0) { ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); } else { ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_RCV); } break; case SPI_CMD_SET_TXINT_BUF: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); if (param != NULL) { devbuf = (DEV_BUFFER *)param; DEV_SPI_XFER_SET_TXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, devbuf->len, 0); DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); } else { DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); } break; case SPI_CMD_SET_RXINT_BUF: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); if (param != NULL) { devbuf = (DEV_BUFFER *)param; DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, devbuf->len, 0); DEV_SPI_XFER_SET_RXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); /* Check transfer align */ DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); } else { DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); } break; case SPI_CMD_TRANSFER_POLLING: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); if (param != NULL) { /* Check transfer align */ DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); *spi_xfer = *((DEV_SPI_TRANSFER *)param); dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); /* Transfer data by poll */ dw_spi_poll_transfer(spi_info_ptr); } else { ercd = E_PAR; } break; case SPI_CMD_TRANSFER_INT: DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); if (param != NULL) { DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); /* Check transfer align */ DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); *spi_xfer = *((DEV_SPI_TRANSFER *)param); dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); /* Transfer data by interrupt */ ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_XFER); } else { ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); } break; /* Master mode only commands */ case SPI_CMD_MST_SET_FREQ: DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); val32 = (uint32_t)param; DW_SPI_CHECK_EXP(val32>0, E_PAR); dw_spi_set_freq(spi_ctrl_ptr, val32); spi_info_ptr->freq = val32; break; case SPI_CMD_MST_SEL_DEV: DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); val32 = (uint32_t)param; if (dw_spi_select_slave(spi_reg_ptr, val32) == 0) { spi_info_ptr->slave = val32; } else { ercd = E_SYS; } break; case SPI_CMD_MST_DSEL_DEV: DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); val32 = (uint32_t)param; if (dw_spi_deselect_slave(spi_reg_ptr, val32) == 0) { spi_info_ptr->slave = SPI_SLAVE_NOT_SELECTED; } else { ercd = E_SYS; } break; /* Slave mode only commands */ default: ercd = E_NOSPT; break; } error_exit: return ercd; }