diff --git a/bsp/ls2kdev/drivers/board.c b/bsp/ls2kdev/drivers/board.c index 30fb59091aa9c798ac2fbe3a91431cc519e17c03..174c7ca8dc4b43b37d37932064ca85f0a2e41e89 100644 --- a/bsp/ls2kdev/drivers/board.c +++ b/bsp/ls2kdev/drivers/board.c @@ -90,7 +90,7 @@ void rt_hw_board_init(void) /* init hardware UART device */ rt_hw_uart_init(); /* set console device */ - rt_console_set_device("uart"); + rt_console_set_device("uart0"); #endif #ifdef RT_USING_HEAP diff --git a/bsp/ls2kdev/drivers/drv_spi.c b/bsp/ls2kdev/drivers/drv_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..83ee66b7a97172f321777bf797da01ca4fe2bd0f --- /dev/null +++ b/bsp/ls2kdev/drivers/drv_spi.c @@ -0,0 +1,269 @@ +#include +#include +#include + +#include +#include + +#include "drv_spi.h" + +#ifdef RT_USING_SPI + + + +static void spi_init(uint8_t spre_spr,uint8_t copl,uint8_t cpha) +{ + //rt_kprintf("SPI initiating with spre_spr:%2X ,copl:%2X ,cpha:%2X\n",spre_spr,copl,cpha); + int d; + SET_SPI(SPSR, 0xc0|(spre_spr&0b00000011)); + SET_SPI(PARAM, 0x40); + SET_SPI(PARAM2,0x01); + SET_SPI(SPER, (spre_spr&0b00001100)>>2); + SET_SPI(SPCR, 0x50|copl<<3|cpha<<2); + SET_SPI(SOFTCS,0xff); +} + + +static void spi_set_csn(uint8_t val) //old method +{ + SET_SPI(SOFTCS,val); +} +// #define RT_USING_SPI_GPIOCS + +#ifdef RT_USING_SPI_GPIOCS +#include +#endif +static void spi_set_cs(unsigned char cs, int new_status) +{ + + if(cs<4){ + unsigned char val = 0; + + val = GET_SPI(SOFTCS); + val |= 0x01 << cs ; // csen=1 + if (new_status) // cs = 1 + { + val |= (0x10 << cs); // csn=1 + } + else // cs = 0 + { + val &= ~(0x10 << cs); // csn=0 + } + SET_SPI(SOFTCS,val); + + return ; + } + #ifdef RT_USING_SPI_GPIOCS + else{ + //rt_kprintf("[Warnning] GPIOCS is an experimental feature: \n "); + //rt_kprintf("[Warnning] GPIO%d will be set to OUTPUT with value %d \n ",cs,new_status); + rt_pin_mode(cs,PIN_MODE_OUTPUT); + rt_pin_write(cs,new_status); + } + #endif +} + +static uint8_t spi_write_for_response(uint8_t data) +{ + uint8_t val; + SET_SPI(TXFIFO,data); + while((GET_SPI(SPSR))&RFEMPTY);//wait for echo + val = GET_SPI(RXFIFO); + return val; +} + + + +static int cmd_spi_init(int argc,char* argv[]) +{ + uint8_t spre_spr,cpol,cpha; + switch (argc) + { + case 2: + + spre_spr=strtoul(argv[1], NULL, 0); + spi_init(spre_spr,0,0); + break; + case 4: + + spre_spr=strtoul(argv[1], NULL, 0); + cpol=strtoul(argv[2], NULL, 0); + cpha=strtoul(argv[3], NULL, 0); + spi_init(spre_spr,0,0); + break; + + default: + printf("\nusage : cmd_spi_init spre_spr \n(cmd_spi_init 0x4 0x0 0x0)\n0x4:div8 0xb:div4096\n"); + break; + } +} +MSH_CMD_EXPORT(cmd_spi_init,cmd_spi_init); + +static int cmd_spi_set_csn(int argc,char* argv[]) +{ + uint8_t val,csn; + switch (argc) + { + case 3: + csn=strtoul(argv[1], NULL, 0); + val=strtoul(argv[2], NULL, 0); + spi_set_cs(csn,val); + break; + + default: + printf("usage:cmd_spi_set_csn csn val\n(0xbf for csn1 enable,0xff for csn1 disable)\n"); + break; + } +} +MSH_CMD_EXPORT(cmd_spi_set_csn,cmd_spi_set_csn); + +static int cmd_spi_write(int argc,char* argv[]) +{ + uint8_t data,resp; + switch (argc) + { + case 2: + + data=strtoul(argv[1], NULL, 0); + resp=spi_write_for_response(data); + printf("resp:%2X\n",resp); + break; + + default: + printf("usage:cmd_spi_write data\n"); + break; + } +} +MSH_CMD_EXPORT(cmd_spi_write,cmd_spi_write); + + +static rt_err_t configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration); +static rt_uint32_t xfer(struct rt_spi_device *device, struct rt_spi_message *message); + +const static unsigned char SPI_DIV_TABLE[]={0b0000,0b0001,0b0100,0b0010,0b0011,0b0101,0b0110,0b0111,0b1000,0b1001,0b1010,0b1011}; + // 2 4 8 16 32 64 128 256 512 1024 2048 4096 +static rt_err_t configure(struct rt_spi_device *device, + struct rt_spi_configuration *configuration) +{ + + + unsigned char cpol = 0; + unsigned char cpha = 0; + + + RT_ASSERT(NULL != device); + RT_ASSERT(NULL != configuration); + + + // baudrate + if (configuration->mode & RT_SPI_CPOL) // cpol + { + cpol = 1; + } + else + { + cpol = 0; + } + if (configuration->mode & RT_SPI_CPHA) // cpha + { + cpha = 1; + } + else + { + cpha = 0; + } + //rt_kprintf("configure: cpol:%d cpha:%d\n",cpol,cpha); + + + float spi_max_speed=((float)APB_MAX_SPEED)/(8.0/(float)APB_FREQSCALE); + //rt_kprintf("spi max speed: %ld\n",(unsigned long)spi_max_speed); + + + uint64_t div=(uint64_t)(spi_max_speed/(float)configuration->max_hz); + //rt_kprintf("require speed: %ld\n",configuration->max_hz); + int ctr=0; + while(div!=1 && ctr<12){ + ctr++; + div=div>>1; + } + //rt_kprintf("spi speed set to: %ld\n",(unsigned long)((spi_max_speed)/(float)(1<parent.user_data); + size = message->length; + + //rt_kprintf("[%s] cs=%d\n", __FUNCTION__, cs); + + // take cs + if (message->cs_take) + { + spi_set_cs(cs, 0); + } + + // send data + send_ptr = message->send_buf; + recv_ptr = message->recv_buf; + while (size--) + { + data = 0xFF; + if (NULL != send_ptr) + { + data = *send_ptr++; + } + + if (NULL != recv_ptr) + { + *recv_ptr++ = spi_write_for_response(data); + } + else + { + spi_write_for_response(data); + } + } + + // release cs + if (message->cs_release) + { + spi_set_cs(cs, 1); + } + + return message->length; +} + +static struct rt_spi_ops loongson_spi_ops = +{ + .configure = configure, + .xfer = xfer +}; + +static struct rt_spi_bus loongson_spi; + +static int loongson_spi_init() +{ + //rt_kprintf("spi_init\n"); + return rt_spi_bus_register(&loongson_spi,"spi",&loongson_spi_ops); +} + +INIT_BOARD_EXPORT(loongson_spi_init); + + +#endif diff --git a/bsp/ls2kdev/drivers/drv_spi.h b/bsp/ls2kdev/drivers/drv_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..08914e979b833616c924d2de332a8c498307566c --- /dev/null +++ b/bsp/ls2kdev/drivers/drv_spi.h @@ -0,0 +1,43 @@ +#ifndef DRV_SPI_H +#define DRV_SPI_H + +#include +#include + + + +#define RFEMPTY 1 +#define KSEG1_STORE8(addr,val) *(volatile char *)(0xffffffffa0000000 | addr) = val +#define KSEG1_LOAD8(addr) *(volatile char *)(0xffffffffa0000000 | addr) + +#define APB_MAX_SPEED 125000000U +#define APB_FREQSCALE (((KSEG1_LOAD8(0xffffffffbfe104d2)>>4)&0x7)+1) + +#define SPI_BASE 0x1fff0220 +#define PMON_ADDR 0xa1000000 +#define FLASH_ADDR 0x000000 + +#define SPCR 0x0 +#define SPSR 0x1 +#define FIFO 0x2 +#define TXFIFO 0x2 +#define RXFIFO 0x2 +#define SPER 0x3 +#define PARAM 0x4 +#define SOFTCS 0x5 +#define PARAM2 0x6 + + + + +#define SET_SPI(addr,val) KSEG1_STORE8(SPI_BASE+addr,val) +#define GET_SPI(addr) KSEG1_LOAD8(SPI_BASE+addr) + + + +//void spi_init(uint8_t ,uint8_t,uint8_t); +//void spi_set_csn(uint8_t); +//uint8_t spi_write_for_response(uint8_t); + + +#endif diff --git a/bsp/ls2kdev/drivers/drv_uart.c b/bsp/ls2kdev/drivers/drv_uart.c index baed70b61f4cd44d77d3dc6b9b7c985904eea5af..7a59d12d3255c285aab7cb17315d7df4eeba5604 100644 --- a/bsp/ls2kdev/drivers/drv_uart.c +++ b/bsp/ls2kdev/drivers/drv_uart.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2020-04-05 bigmagic Initial version + * 2020-10-28 ma Buadrate & Multi-Port support */ /** @@ -21,22 +22,51 @@ #define TRUE 1 #define FALSE 0 - +const struct serial_configure config_uart0 = { + BAUD_RATE_115200, /* 921600 bits/s */ + DATA_BITS_8, /* 8 databits */ + STOP_BITS_1, /* 1 stopbit */ + PARITY_NONE, /* No parity */ + BIT_ORDER_LSB, /* LSB first sent */ + NRZ_NORMAL, /* Normal mode */ + RT_SERIAL_RB_BUFSZ, /* Buffer size */ + 0 +}; struct rt_uart_ls2k { void *base; rt_uint32_t IRQ; }; +static rt_err_t ls2k_uart_set_buad(struct rt_serial_device *serial,struct serial_configure *cfg) +{ + + struct rt_uart_ls2k *uart_dev = RT_NULL; + rt_err_t ret=RT_EOK; + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart_dev = (struct rt_uart_ls2k *)serial->parent.user_data; + uint64_t brtc = (125000000U) / (16*(cfg->baud_rate)); + UART_LCR(uart_dev->base)=0x80; // Activate buadcfg + UART_LSB(uart_dev->base)= brtc & 0xff; + UART_MSB(uart_dev->base)= brtc >> 8; + + if(((((short)UART_MSB(uart_dev->base))<<8) | UART_LSB(uart_dev->base)) != brtc) ret=RT_ERROR; + + UART_LCR(uart_dev->base)= CFCR_8BITS;// Back to normal + UART_MCR(uart_dev->base)= MCR_IENABLE/* | MCR_DTR | MCR_RTS*/; + UART_IER(uart_dev->base) = 0; +} static rt_err_t ls2k_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct rt_uart_ls2k *uart_dev = RT_NULL; RT_ASSERT(serial != RT_NULL); RT_ASSERT(cfg != RT_NULL); - + ls2k_uart_set_buad(serial,cfg); uart_dev = (struct rt_uart_ls2k *)serial->parent.user_data; - + HWREG8(0xffffffffbfe10428)=0x1f;// Enable Multi-Port Support, by default it's 0x11 ,which means UART0 & UART4 Controller is in single port mode. UART_IER(uart_dev->base) = 0; /* clear interrupt */ UART_FCR(uart_dev->base) = 0xc1; /* reset UART Rx/Tx */ /* set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ @@ -154,25 +184,47 @@ struct rt_uart_ls2k uart_dev0 = (void *)UARTx_BASE(0), LS2K_UART_0_1_2_3_IRQ, }; -struct rt_serial_device serial; +struct rt_uart_ls2k uart_dev4 = +{ + (void *)UARTx_BASE(4), + LS2K_UART_4_5_6_7_IRQ , +}; + + +struct rt_serial_device serial,serial4; void rt_hw_uart_init(void) { - struct rt_uart_ls2k *uart; + //UART0_1_ENABLE=0xff; + struct rt_uart_ls2k *uart,*uart4; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + uart = &uart_dev0; + uart4=&uart_dev4; serial.ops = &ls2k_uart_ops; - serial.config = config; + serial.config = config_uart0; + + serial4.ops= &ls2k_uart_ops; + serial4.config=config; - rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial, "UART"); + + rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial, "UART0"); + rt_hw_interrupt_install(uart4->IRQ, uart_irq_handler, &serial4, "UART4"); /* register UART device */ rt_hw_serial_register(&serial, - "uart", + "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + + rt_hw_serial_register(&serial4, + "uart4", + RT_DEVICE_FLAG_RDWR| RT_DEVICE_FLAG_INT_RX, + &uart_dev4); + } /*@}*/