123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #include "board.h"
- typedef struct
- {
- unsigned int spi; //SPI对象
- int speed; //SPI速度
- int data_bits; //数据位
- unsigned int mode;
- unsigned int endian;
- unsigned int clk_port;
- int clk_pin;
- unsigned int miso_port;
- int miso_pin;
- unsigned int mosi_port;
- int mosi_pin;
- int af;
- } hw_spi_t;
- typedef struct
- {
- unsigned int spi; //SPI对象
- unsigned int cs_port;
- int cs_pin;
- } hw_spi_device_t;
- static hw_spi_t hw_spi_map[HW_SPI_NUMBER] = {
- { SPI0, 2000000, 8, SPI_CK_PL_LOW_PH_1EDGE, SPI_ENDIAN_MSB, GPIOA, 5, GPIOA, 6, GPIOA, 7, GPIO_AF_0 }
- };
- static hw_spi_device_t hw_spi_device_map[HW_SPI_DEVICE_NUMBER] = {
- { SPI0, GPIOB, 2 },
- { SPI0, GPIOB, 1 },
- { SPI0, GPIOB, 0 }
- };
- #define SPI_DEVICE_TAKE(a) GPIO_BOP(hw_spi_device_map[a].cs_port) = 1 << (hw_spi_device_map[a].cs_pin+16)
- #define SPI_DEVICE_UNTAKE(a) GPIO_BOP(hw_spi_device_map[a].cs_port) = 1 << (hw_spi_device_map[a].cs_pin)
- /**
- * 读写一个字节
- *
- * @author LXZ (011621)
- *
- * @param spi
- * @param value
- *
- * @return rt_uint16_t
- */
- static uint16_t hw_spi_readwrite_byte(unsigned int spi, uint16_t value) {
- /* loop while data register in not emplty */
- while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_TBE));
- /* send half word through the SPI peripheral */
- spi_i2s_data_transmit(spi,value);
- /* wait to receive a half word */
- while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_RBNE));
- /* return the half word read from the SPI bus */
- return spi_i2s_data_receive(spi);
- }
- /**
- * 读写连续数据
- *
- * @author LXZ (011621)
- *
- * @param spi
- * @param src
- * @param dst
- * @param length
- *
- * @return rt_uint32_t
- */
- int hw_spi_readwrite(uint8_t port, const uint8_t *cmd, uint8_t *dst, int size) {
- int i = 0;
- uint8_t temp = 0;
- unsigned int spi = hw_spi_device_map[port].spi;
- while (i < size) {
- /* loop while data register in not emplty */
- while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_TBE));
- if (cmd != 0) {
- temp = cmd[i];
- }
- else {
- temp = 0xff;
- }
- /* send byte through the SPI peripheral */
- spi_i2s_data_transmit(spi,temp);
- /* wait to receive a byte */
- while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_RBNE));
- temp = (uint8_t)spi_i2s_data_receive(spi);
- if (dst != 0) {
- dst[i] = temp;
- }
- i++;
- }
- return size;
- }
- /**
- * 选中设备
- *
- * @author LXZ (011621)
- *
- * @param port
- */
- void hw_spi_device_take(int port) {
- SPI_DEVICE_TAKE(port);
- }
- /**
- * 释放设备
- *
- * @author LXZ (011621)
- *
- * @param port
- */
- void hw_spi_device_release(int port) {
- SPI_DEVICE_UNTAKE(port);
- }
- /**
- * 硬件SPI初始化
- *
- * @author LXZ (011621)
- *
- * @param void
- */
- void hw_spi_init(void) {
- spi_parameter_struct spi_init_struct;
- int index = 0;
- unsigned int spi;
- int clk;
- int apb;
- unsigned long port;
- int pin;
- int af;
- int frame_size;
- while (index < HW_SPI_DEVICE_NUMBER) {
- port = (uint32_t)hw_spi_device_map[index].cs_port;
- pin = 1 << hw_spi_device_map[index].cs_pin;
- if (port != 0) {
- //使能时钟
- rcu_periph_clock_enable(rcu_periph_clock_bit(port));
- //配置IO为输出
- gpio_mode_set(port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, pin);
- gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
- }
- GPIO_BOP(hw_spi_device_map[index].cs_port) = 1 << (hw_spi_device_map[index].cs_pin);
- index++;
- }
- index = 0;
- while (index < HW_SPI_NUMBER) {
- //CLK
- port = (uint32_t)hw_spi_map[index].clk_port;
- pin = 1 << hw_spi_map[index].clk_pin;
- af = hw_spi_map[index].af;
- if (port != 0) {
- //使能时钟
- rcu_periph_clock_enable(rcu_periph_clock_bit(port));
- //配置IO为AF
- gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
- gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
- gpio_af_set(port, af, pin);
- }
- //MISO
- port = (uint32_t)hw_spi_map[index].miso_port;
- pin = 1 << hw_spi_map[index].miso_pin;
- if (port != 0) {
- //使能时钟
- rcu_periph_clock_enable(rcu_periph_clock_bit(port));
- //配置IO为AF
- gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
- gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
- gpio_af_set(port, af, pin);
- }
- //MOSI
- port = (uint32_t)hw_spi_map[index].mosi_port;
- pin = 1 << hw_spi_map[index].mosi_pin;
- if (port != 0) {
- //使能时钟
- rcu_periph_clock_enable(rcu_periph_clock_bit(port));
- //配置IO为AF
- gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
- gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
- gpio_af_set(port, af, pin);
- }
- //SPI外设时钟
- spi = hw_spi_map[index].spi;
- rcu_periph_clock_enable(rcu_periph_clock_bit(spi));
- //数据帧长度
- if(hw_spi_map[index].data_bits==16)
- {
- frame_size =SPI_FRAMESIZE_16BIT;
- }
- else
- {
- frame_size =SPI_FRAMESIZE_8BIT;
- }
- //SPI速度
- clk = HW_BOART_CORE_FREQ*1000000;
- if (hw_spi_map[index].speed >= clk / 2) {
- apb = SPI_PSC_2;
- }
- else if (hw_spi_map[index].speed >= clk / 4) {
- apb = SPI_PSC_4;
- }
- else if (hw_spi_map[index].speed >= clk / 8) {
- apb = SPI_PSC_8;
- }
- else if (hw_spi_map[index].speed >= clk / 16) {
- apb = SPI_PSC_16;
- }
- else if (hw_spi_map[index].speed >= clk / 32) {
- apb = SPI_PSC_32;
- }
- else if (hw_spi_map[index].speed >= clk / 64) {
- apb = SPI_PSC_64;
- }
- else if (hw_spi_map[index].speed >= clk / 128) {
- apb = SPI_PSC_128;
- }
- else {
- /* min prescaler 256 */
- apb = SPI_PSC_256;
- }
- spi_i2s_deinit(spi);
- spi_struct_para_init(&spi_init_struct);
- /* SPI0 parameter config */
- spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
- spi_init_struct.device_mode = SPI_MASTER;
- spi_init_struct.frame_size = frame_size;
- spi_init_struct.clock_polarity_phase = hw_spi_map[index].mode;
- spi_init_struct.nss = SPI_NSS_SOFT;
- spi_init_struct.prescale = SPI_PSC_256;
- spi_init_struct.endian = hw_spi_map[index].endian;
- spi_init(spi, &spi_init_struct);
- /* enable SPI0 */
- spi_enable(spi);
- hw_spi_readwrite_byte(spi, 0xff);
- index++;
- }
- }
|