├── .github └── workflows │ └── release.yml ├── LICENSE ├── README.md ├── Version ├── boards.txt ├── cores └── sg200x │ ├── ControlPWM.cpp │ ├── HardwareSerial.cpp │ ├── Mailbox.cpp │ ├── Main.cpp │ ├── Print.cpp │ ├── README.md │ ├── Stream.cpp │ ├── System.cpp │ ├── Tone.cpp │ ├── WMath.cpp │ ├── WString.cpp │ ├── bsp │ ├── drivers │ │ ├── csi_adc.c │ │ ├── csi_common.c │ │ ├── csi_dma.c │ │ ├── csi_dma_consts.c │ │ ├── csi_gpio.c │ │ ├── csi_gpio_pin.c │ │ ├── csi_iic.c │ │ ├── csi_pin.c │ │ ├── csi_pwm.c │ │ ├── csi_spi.c │ │ ├── csi_target_get.c │ │ ├── csi_uart.c │ │ ├── cvi_dma.c │ │ ├── cvi_mailbox.c │ │ └── cvi_spinlock.c │ ├── hal │ │ ├── dw │ │ │ ├── dw_iic_ll.c │ │ │ ├── dw_spi_ll.c │ │ │ └── dw_uart_ll.c │ │ ├── hal_dma.c │ │ └── hal_sysdma.c │ ├── include │ │ ├── csi │ │ │ ├── csi_adc.h │ │ │ ├── csi_common.h │ │ │ ├── csi_dma.h │ │ │ ├── csi_gpio.h │ │ │ ├── csi_gpio_pin.h │ │ │ ├── csi_iic.h │ │ │ ├── csi_list.h │ │ │ ├── csi_pin.h │ │ │ ├── csi_pwm.h │ │ │ ├── csi_riscv_gcc.h │ │ │ ├── csi_spi.h │ │ │ └── csi_uart.h │ │ ├── cvi │ │ │ ├── cvi_dma.h │ │ │ ├── cvi_mailbox.h │ │ │ ├── cvi_pwm.h │ │ │ └── cvi_spinlock.h │ │ ├── encoding.h │ │ ├── hal │ │ │ ├── dw │ │ │ │ ├── dw_cvi_dma_ll.h │ │ │ │ ├── dw_dma_ll.h │ │ │ │ ├── dw_gpio_ll.h │ │ │ │ ├── dw_iic_ll.h │ │ │ │ ├── dw_spi_ll.h │ │ │ │ └── dw_uart_ll.h │ │ │ ├── hal_adc.h │ │ │ ├── hal_dma.h │ │ │ ├── hal_pin.h │ │ │ └── hal_sysdma.h │ │ ├── mmio.h │ │ └── resource_table.h │ └── startup │ │ ├── interrupt.c │ │ ├── start.S │ │ └── tick.c │ ├── include │ ├── Arduino.h │ ├── ControlPWM.h │ ├── HardwareSerial.h │ ├── Print.h │ ├── Printable.h │ ├── RingBuffer.h │ ├── Stream.h │ ├── Tone.h │ ├── WCharacter.h │ ├── WInterrupts.h │ ├── WMath.h │ ├── WString.h │ ├── binary.h │ ├── common.h │ ├── mailbox.h │ ├── misc.h │ ├── pgmspace.h │ ├── stdlib_noniso.h │ ├── wiring_analog.h │ ├── wiring_constants.h │ ├── wiring_digital.h │ ├── wiring_pulse.h │ └── wiring_shift.h │ ├── interrupts.c │ ├── stdlib_noniso.c │ ├── time.c │ ├── wiring_analog.c │ ├── wiring_digital.c │ ├── wiring_pulse.cpp │ └── wiring_shift.c ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ ├── install_preferences.png │ ├── install_sg200x.png │ ├── pin.png │ ├── select_board.png │ ├── select_example.png │ └── upload.png │ ├── conf.py │ ├── examples.rst │ ├── examples │ └── led.rst │ ├── get-started │ ├── getting-started.rst │ └── quick-guides.rst │ ├── index.rst │ ├── libraries.rst │ └── libraries │ ├── adc.rst │ ├── gpio.rst │ ├── i2c.rst │ ├── mailbox.rst │ ├── pwm.rst │ ├── serial.rst │ └── spi.rst ├── libraries ├── SPI │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── SPI.cpp │ │ └── SPI.h └── Wire │ ├── keywords.txt │ ├── library.properties │ └── src │ ├── Wire.cpp │ └── Wire.h ├── package.json ├── package ├── _vercmp.sh ├── config.json ├── package_sg200x_index.template.json └── release.sh ├── platform.txt ├── programmers.txt ├── tools ├── .gitignore └── burntool │ ├── README.md │ └── burntool.py └── variants ├── duo ├── link.ld ├── variant.h ├── variant_pin_maps.c ├── variant_pins.h └── variant_soc.h └── duo256 ├── link.ld ├── variant.h ├── variant_pin_maps.c └── variant_pins.h /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: arduino duo release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | - 'V*.*.*' 8 | paths-ignore: 9 | - '.github/workflows/docs.yml' 10 | - 'docs/**' 11 | workflow_dispatch: 12 | inputs: 13 | force-update: 14 | description: (DANGER!!) force updating the package_sg200x_index.json file 15 | required: false 16 | type: string 17 | 18 | concurrency: 19 | group: "pages" 20 | cancel-in-progress: false 21 | 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | permissions: 26 | contents: write 27 | 28 | steps: 29 | - name: checkout current triggered tag 30 | if: github.event_name == 'push' 31 | uses: actions/checkout@v4 32 | with: 33 | fetch-depth: 0 34 | - name: checkout input tag 35 | if: github.event_name == 'workflow_dispatch' 36 | uses: actions/checkout@v4 37 | with: 38 | ref: ${{ inputs.tag }} 39 | fetch-depth: 0 40 | - name: setup python 41 | uses: actions/setup-python@v5 42 | with: 43 | python-version: '3.x' 44 | 45 | - name: Install Dependencies 46 | run: pip3 install sphinx sphinx-copybutton sphinx_multiversion sphinx_rtd_theme 47 | 48 | - name: Build 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | id: package-build 52 | run: | 53 | set -e 54 | echo $PWD 55 | echo $GITHUB_WORKSPACE 56 | cd ./package/ 57 | ./release.sh 58 | . $GITHUB_ENV 59 | if ! [[ ${INDEX_JSON_STATUS} =~ ^UPDATED_JSON:1 ]]; then 60 | echo "The arduino-sophgo package no updates!" >&2 61 | echo "Something wroing with the version number?" >&2 62 | if [[ "${{ inputs.force-update }}" =~ ^(1|(Y|y)((E|e)(S|s))?|(T|t)rue)$ ]]; then 63 | echo "force updating ..." >&2 64 | else 65 | exit 1 66 | fi 67 | fi 68 | mv $GITHUB_WORKSPACE/../arduino-sophgo.zip $GITHUB_WORKSPACE/ 69 | mv $GITHUB_WORKSPACE/../$INDEX_JSON_FILE_NAME $GITHUB_WORKSPACE/ 70 | mv $GITHUB_WORKSPACE/../burntool.tar.gz $GITHUB_WORKSPACE/ 71 | mv $GITHUB_WORKSPACE/../burntool.zip $GITHUB_WORKSPACE/ 72 | 73 | - name: Build Doc 74 | run: | 75 | cd $GITHUB_WORKSPACE/docs 76 | make html 77 | tar -zcvf docs_html.tar.gz ./build/ 78 | mv docs_html.tar.gz $GITHUB_WORKSPACE/ 79 | 80 | - name: Create Release and Upload Release Asset 81 | uses: softprops/action-gh-release@v2 82 | if: startsWith(github.ref, 'refs/tags/') 83 | env: 84 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | with: 86 | tag_name: ${{ github.ref }} 87 | name: Release ${{ github.ref_name }} 88 | body: TODO New Release. 89 | draft: false 90 | prerelease: false 91 | files: | 92 | arduino-sophgo.zip 93 | ${{ steps.package-build.outputs.index_json_file_name }} 94 | burntool.tar.gz 95 | burntool.zip 96 | docs_html.tar.gz 97 | - name: Install GitHub CLI for updating package index file within the specific release 98 | run: sudo apt-get install -y gh 99 | - name: Authenticate GitHub CLI 100 | run: gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" 101 | - name: Get release by tag 102 | id: get_release 103 | env: 104 | TAG_NAME: ${{ steps.package-build.outputs.index_json_file_release_tag }} 105 | run: | 106 | RELEASE_ID=$(gh api repos/$GITHUB_REPOSITORY/releases/tags/$TAG_NAME --jq '.id') 107 | echo "id=$RELEASE_ID" >>$GITHUB_OUTPUT 108 | - name: Upload new asset to release 109 | env: 110 | FILE_PATH: ${{ steps.package-build.outputs.index_json_file_name }} 111 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 112 | run: | 113 | set -e 114 | _do() { 115 | echo ">>>" "$@" >&2 116 | "$@" 117 | } 118 | RELEASE_ID=${{ steps.get_release.outputs.id }} 119 | FILE_NAME=$(basename $FILE_PATH) 120 | if ! [[ -f "$FILE_PATH" ]]; then 121 | echo "file '$FILE_PATH' not exist" >&2 122 | exit 1 123 | fi 124 | ASSET_ID=$(_do gh api repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets --jq ".[] | select(.name == \"$FILE_NAME\") | .id") 125 | if [[ -n "$ASSET_ID" ]]; then 126 | # delete the old asset 127 | gh api \ 128 | --method DELETE \ 129 | -H "Accept: application/vnd.github+json" \ 130 | -H "X-GitHub-Api-Version: 2022-11-28" \ 131 | /repos/$GITHUB_REPOSITORY/releases/assets/$ASSET_ID 132 | fi 133 | # upload the new asset 134 | # gh api not work, weird 135 | curl -L -X POST \ 136 | -H "Accept: application/vnd.github+json" \ 137 | -H "Authorization: Bearer $GITHUB_TOKEN" \ 138 | -H "X-GitHub-Api-Version: 2022-11-28" \ 139 | -H "Content-Type: application/octet-stream" \ 140 | "https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets?name=$FILE_NAME" \ 141 | --data-binary "@$FILE_PATH" 142 | - name: Check release assets 143 | run: | 144 | RELEASE_ID=${{ steps.get_release.outputs.id }} 145 | gh api repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets --jq '.[].name' 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | [https://milkv.io/docs/duo/getting-started/arduino](https://milkv.io/docs/duo/getting-started/arduino) -------------------------------------------------------------------------------- /Version: -------------------------------------------------------------------------------- 1 | 0.2.4 2 | -------------------------------------------------------------------------------- /boards.txt: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | ### Boards Start ### 3 | ############################################################## 4 | 5 | duo.name=Duo Dev Module 6 | duo.vid.0=0x3346 7 | duo.pid.0=0x1009 8 | 9 | duo.upload.tool=burntool_py 10 | duo.upload.tool.default=burntool_py 11 | 12 | duo.upload.flags= 13 | duo.upload.extra_flags= 14 | duo.upload.use_1200bps_touch=false 15 | duo.upload.wait_for_upload_port=false 16 | 17 | duo.serial.disableDTR=true 18 | duo.serial.disableRTS=true 19 | 20 | duo.build.tarch=riscv64 21 | duo.build.target=unknown 22 | duo.build.mcu=sg200x 23 | duo.build.core=sg200x 24 | duo.build.variant=duo 25 | duo.build.board=DUO_DEV 26 | duo.build.extra_flags= 27 | duo.build.bootloader_addr=0x0 28 | duo.build.start_addr=0x83f40000 29 | duo.build.image_size=0xc0000 30 | 31 | duo.build.f_cpu=25000000L 32 | duo.build.img_freq=48m 33 | duo.build.partitions=default 34 | duo.build.defines= 35 | duo.build.ldscript=link.ld 36 | 37 | ############################################################## 38 | 39 | duo256.name=Duo256 Dev Module 40 | duo256.vid.0=0x3346 41 | duo256.pid.0=0x1009 42 | 43 | duo256.upload.tool=burntool_py 44 | duo256.upload.tool.default=burntool_py 45 | 46 | duo256.upload.flags= 47 | duo256.upload.extra_flags= 48 | duo256.upload.use_1200bps_touch=false 49 | duo256.upload.wait_for_upload_port=false 50 | 51 | duo256.serial.disableDTR=true 52 | duo256.serial.disableRTS=true 53 | 54 | duo256.build.tarch=riscv64 55 | duo256.build.target=unknown 56 | duo256.build.mcu=sg200x 57 | duo256.build.core=sg200x 58 | duo256.build.variant=duo256 59 | duo256.build.board=DUO_DEV 60 | duo256.build.extra_flags= 61 | duo256.build.bootloader_addr=0x0 62 | duo256.build.start_addr=0x8fe00000 63 | duo256.build.image_size=0x200000 64 | 65 | duo256.build.f_cpu=25000000L 66 | duo256.build.img_freq=48m 67 | duo256.build.partitions=default 68 | duo256.build.defines= 69 | duo256.build.ldscript=link.ld 70 | -------------------------------------------------------------------------------- /cores/sg200x/ControlPWM.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "common.h" 3 | #include "csi_gpio_pin.h" 4 | #include "csi_pin.h" 5 | #include "csi_pwm.h" 6 | #include "wiring_analog.h" 7 | #include "ControlPWM.h" 8 | 9 | int channel = -1; 10 | static csi_pwm_t active_pwm_servo; 11 | extern dev_pin_map_t pwm_map[]; 12 | 13 | void setPWM(uint8_t _pin, unsigned int _pulse, unsigned int _period) 14 | { 15 | const dev_pin_map_t* pwm_pin = target_pin_number_to_dev(_pin, pwm_map, 0xFF); 16 | if (pwm_pin == NULL) { 17 | pr_err("pin GPIO %d is not used as PWM func\n", _pin); 18 | return; 19 | } 20 | 21 | uint8_t pwm_idx = pwm_pin->idx >> 2; 22 | uint8_t pwm_channel = pwm_pin->idx & 0x3; 23 | 24 | if (csi_pin_set_mux(pwm_pin->name, pwm_pin->func)) { 25 | pr_err("pin GPIO %d fails to config as PWM func\n", _pin); 26 | return; 27 | }; 28 | 29 | csi_error_t ret_status = csi_pwm_init(&active_pwm_servo, pwm_idx); 30 | if (ret_status != CSI_OK) { 31 | pr_err("GPIO pin %d init failed\n", _pin); 32 | return; 33 | } 34 | channel = pwm_channel; 35 | 36 | csi_pwm_out_stop(&active_pwm_servo, pwm_channel); 37 | csi_pwm_out_config_continuous(&active_pwm_servo, pwm_channel, _period, 38 | 0, PWM_POLARITY_HIGH); 39 | csi_pwm_out_start(&active_pwm_servo, pwm_channel); 40 | 41 | csi_pwm_out_stop(&active_pwm_servo, pwm_channel); 42 | csi_pwm_out_config_continuous(&active_pwm_servo, pwm_channel, _period, 43 | _pulse, PWM_POLARITY_HIGH); 44 | csi_pwm_out_start(&active_pwm_servo, pwm_channel); 45 | } 46 | -------------------------------------------------------------------------------- /cores/sg200x/HardwareSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include "csi_pin.h" 9 | #include "HardwareSerial.h" 10 | #include "Arduino.h" 11 | 12 | #if SERIAL_INTERFACES_COUNT > 0 13 | HardwareSerial Serial0(0, PIN_UART0_RX, PIN_UART0_TX); 14 | #endif 15 | #if SERIAL_INTERFACES_COUNT > 1 16 | HardwareSerial Serial1(1, PIN_UART1_RX, PIN_UART1_TX); 17 | #endif 18 | #if SERIAL_INTERFACES_COUNT > 2 19 | HardwareSerial Serial2(2, PIN_UART2_RX, PIN_UART2_TX); 20 | #endif 21 | #if SERIAL_INTERFACES_COUNT > 3 22 | HardwareSerial Serial3(3, PIN_UART3_RX, PIN_UART3_TX); 23 | #endif 24 | #if SERIAL_INTERFACES_COUNT > 4 25 | HardwareSerial Serial4(4, PIN_UART4_RX, PIN_UART4_TX); 26 | #endif 27 | 28 | extern dev_pin_map_t uart_rx_map[]; 29 | extern dev_pin_map_t uart_tx_map[]; 30 | 31 | extern "C" void * __dso_handle = 0 ; 32 | 33 | HardwareSerial::HardwareSerial(int uartNum, uint8_t rx, uint8_t tx) : 34 | _uartNum(uartNum), 35 | _timeout(1000), 36 | _data_valid(false), 37 | _rxPin(rx), 38 | _txPin(tx) 39 | { 40 | } 41 | 42 | HardwareSerial::~HardwareSerial() 43 | { 44 | end(); 45 | } 46 | 47 | void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin) 48 | { 49 | if (rxPin < 0) { 50 | rxPin = _rxPin; 51 | } 52 | 53 | if (txPin < 0) { 54 | txPin = _txPin; 55 | } 56 | 57 | const dev_pin_map_t* rx_pin = target_pin_number_to_dev(rxPin, uart_rx_map, _uartNum); 58 | const dev_pin_map_t* tx_pin = target_pin_number_to_dev(txPin, uart_tx_map, _uartNum); 59 | 60 | if (rx_pin == NULL || tx_pin == NULL) { 61 | pr_err("pin GPIO %d or %d are not used as Uart func\n", rxPin, txPin); 62 | return; 63 | } 64 | 65 | if (csi_pin_set_mux(rx_pin->name, rx_pin->func)) { 66 | pr_err("pin GPIO %d fails to config as Uart_rx func\n", rxPin); 67 | return; 68 | } 69 | 70 | if (csi_pin_set_mux(tx_pin->name, tx_pin->func)) { 71 | pr_err("pin GPIO %d fails to config as Uart_tx func\n", txPin); 72 | return; 73 | } 74 | 75 | csi_uart_init(&_uart, _uartNum); 76 | 77 | _rxPin = rxPin; 78 | _txPin = txPin; 79 | 80 | csi_uart_format(&_uart, SERIAL_DATA(config), SERIAL_PARITY(config), SERIAL_STOP(config)); 81 | csi_uart_baud(&_uart, baud); 82 | } 83 | 84 | void HardwareSerial::end() 85 | { 86 | if (_uart.dev.reg_base) { 87 | csi_uart_uninit(&_uart); 88 | } 89 | } 90 | 91 | int HardwareSerial::available(void) 92 | { 93 | if (_data_valid) { 94 | return 1; 95 | } 96 | 97 | int32_t ret = csi_uart_receive(&_uart, &_data, 1, 0); 98 | if (ret) { 99 | _data_valid = true; 100 | return 1; 101 | } 102 | 103 | return 0; 104 | } 105 | 106 | int HardwareSerial::read(void) 107 | { 108 | if (_data_valid) { 109 | _data_valid = false; 110 | return _data; 111 | } 112 | 113 | int32_t ret = csi_uart_receive(&_uart, &_data, 1, _timeout); 114 | if (ret) { 115 | return _data; 116 | } else { 117 | while (1); 118 | return -1; 119 | } 120 | } 121 | 122 | int HardwareSerial::peek(void) 123 | { 124 | if (_data_valid) { 125 | return _data; 126 | } 127 | 128 | int32_t ret = csi_uart_receive(&_uart, &_data, 1, _timeout); 129 | if (ret) { 130 | _data_valid = true; 131 | return _data; 132 | } else { 133 | return -1; 134 | } 135 | } 136 | 137 | // read characters into buffer 138 | // terminates if size characters have been read, or no further are pending 139 | // returns the number of characters placed in the buffer 140 | // the buffer is NOT null terminated. 141 | size_t HardwareSerial::read(uint8_t *buffer, size_t size) 142 | { 143 | if (size == 0) { 144 | return 0; 145 | } 146 | 147 | if (_data_valid) { 148 | buffer[0] = _data; 149 | _data_valid = false; 150 | buffer++; 151 | size--; 152 | } 153 | if (size > 0) { 154 | return csi_uart_receive(&_uart, buffer, size, _timeout) + 1; 155 | } else { 156 | return 1; 157 | } 158 | } 159 | 160 | size_t HardwareSerial::write(uint8_t c) 161 | { 162 | csi_uart_putc(&_uart, c); 163 | return 1; 164 | } 165 | 166 | size_t HardwareSerial::write(const uint8_t *buffer, size_t size) 167 | { 168 | return csi_uart_send(&_uart, buffer, size, _timeout); 169 | } 170 | 171 | HardwareSerial::operator bool() const 172 | { 173 | return _uart.dev.reg_base != 0; 174 | } 175 | 176 | extern "C" 177 | { 178 | char _SerialPutChar(char c) 179 | { 180 | if (Serial) 181 | { 182 | Serial.write(c); 183 | return (c & 0xFF); 184 | } 185 | 186 | return 0; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /cores/sg200x/Mailbox.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "Arduino.h" 6 | #include 7 | #include "mailbox.h" 8 | 9 | #include "cvi_mailbox.h" 10 | 11 | #define SOC_MBOX_INTERRUPT 0x3D 12 | 13 | static volatile mailbox_set_register *mbox_reg; 14 | static volatile mailbox_done_register *mbox_done_reg; 15 | static volatile uint32_t *mailbox_context; 16 | 17 | static void (*callbacks[NUM_MAILBOX_CHANNELS])(MailboxMsg); 18 | 19 | MailboxMsg MBoxMsg[NUM_MAILBOX_CHANNELS]; 20 | 21 | void mailbox_register (int channel, void(*callback)(MailboxMsg)) 22 | { 23 | if (channel >= 0 && channel < NUM_MAILBOX_CHANNELS) { 24 | callbacks[channel] = callback; 25 | } 26 | } 27 | 28 | void mailbox_unregister (int channel) 29 | { 30 | if (channel >= 0 && channel < NUM_MAILBOX_CHANNELS) { 31 | callbacks[channel] = 0; 32 | } 33 | } 34 | 35 | void mailbox_disable_receive (int channel) 36 | { 37 | mbox_reg->cpu_mbox_set[SEND_TO_CPU1].cpu_mbox_int_mask.mbox_int_mask |= 1 << channel; 38 | } 39 | 40 | void mailbox_enable_receive (int channel) 41 | { 42 | mbox_reg->cpu_mbox_set[SEND_TO_CPU1].cpu_mbox_int_mask.mbox_int_mask &= ~(1 << channel); 43 | } 44 | 45 | static void do_callback (int channel, MailboxMsg& msg) 46 | { 47 | void (*cb)(MailboxMsg) = callbacks[channel]; 48 | if (cb) { 49 | cb(msg); 50 | } 51 | } 52 | 53 | static void mailbox_read (int channel, MailboxMsg& msg) 54 | { 55 | unsigned int i; 56 | 57 | /* Copy channel data into MailboxMsg object */ 58 | msg.channel = channel; 59 | 60 | msg.data= (uint32_t *)(mailbox_context + (4 * channel)); 61 | 62 | mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_clr.mbox_int_clr = 1 << channel; 63 | mbox_reg->cpu_mbox_en[RECEIVE_CPU].mbox_info &= ~(1 << channel); 64 | } 65 | 66 | void mailbox_write (MailboxMsg& msg) 67 | { 68 | 69 | uint32_t *ptr; 70 | 71 | ptr = (uint32_t *)(mailbox_context + (4 * msg.channel)); 72 | 73 | ptr = static_cast(msg.data); 74 | 75 | // clear mailbox 76 | mbox_reg->cpu_mbox_set[SEND_TO_CPU1].cpu_mbox_int_clr.mbox_int_clr = (1 << msg.channel); 77 | // trigger mailbox valid to rtos 78 | mbox_reg->cpu_mbox_en[SEND_TO_CPU1].mbox_info |= (1 << msg.channel); 79 | mbox_reg->mbox_set.mbox_set = (1 << msg.channel); 80 | } 81 | 82 | static int mailbox_isr(int irqn, void *priv) 83 | { 84 | int i; 85 | uint32_t sts; 86 | MailboxMsg msg; 87 | uint8_t valid_val; 88 | 89 | uint8_t set_val; 90 | set_val = mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_int.mbox_int; 91 | 92 | for (i = 0; i < MAILBOX_MAX_NUM; i++) 93 | { 94 | valid_val = set_val & (1 << i); 95 | if (valid_val) 96 | { 97 | mailbox_read(i, msg); 98 | do_callback(i, msg); 99 | } 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | static void mailbox_hardware_init (void) 106 | { 107 | } 108 | 109 | static void mailbox_interrupts_init (bool master) 110 | { 111 | disable_irq(SOC_MBOX_INTERRUPT); 112 | 113 | if (master) 114 | mailbox_hardware_init(); 115 | 116 | attach_irq(SOC_MBOX_INTERRUPT, &mailbox_isr, 0, "mailbox int", NULL); 117 | enable_irq(SOC_MBOX_INTERRUPT); 118 | } 119 | 120 | void mailbox_init (bool master) 121 | { 122 | int i; 123 | mbox_reg = (struct mailbox_set_register *)MAILBOX_REG_BASE; 124 | mbox_done_reg = (struct mailbox_done_register *)(MAILBOX_REG_BASE + 2); 125 | mailbox_context = (uint32_t *)(MAILBOX_REG_BUFF); 126 | 127 | for (i = 0; i < MAILBOX_MAX_NUM; i++) 128 | mailbox_context[i] = 0; 129 | 130 | memset(callbacks, 0, sizeof(callbacks)); 131 | mailbox_interrupts_init(master); 132 | } 133 | -------------------------------------------------------------------------------- /cores/sg200x/Main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #define ARDUINO_MAIN 20 | #include "Arduino.h" 21 | #include "resource_table.h" 22 | 23 | // Weak empty variant initialization function. 24 | // May be redefined by variant files. 25 | void initVariant() __attribute__((weak)); 26 | void initVariant() { } 27 | 28 | // Initialize C library 29 | extern "C" void __libc_init_array(void); 30 | 31 | /* 32 | * \brief Main entry point of Arduino application 33 | */ 34 | int main(void) 35 | { 36 | __libc_init_array(); 37 | 38 | init(); 39 | 40 | initVariant(); 41 | 42 | delay(1); 43 | 44 | setup(); 45 | 46 | for (;;) 47 | { 48 | loop(); 49 | //if (arduino::serialEventRun) arduino::serialEventRun(); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /cores/sg200x/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/cores/sg200x/README.md -------------------------------------------------------------------------------- /cores/sg200x/System.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "common.h" 6 | #include "csi_gpio_pin.h" 7 | #include "csi_pin.h" 8 | #include "csi_adc.h" 9 | #include "csi_dma.h" 10 | #include "HardwareSerial.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #ifdef USE_SPI_DMA 17 | static csi_dma_t dma_hdl; 18 | #endif 19 | 20 | void init(void) 21 | { 22 | irq_init(); 23 | tick_init(); 24 | 25 | #ifdef DEBUG_SERIAL 26 | DEBUG_SERIAL.begin(115200); 27 | #endif 28 | 29 | #ifdef USE_SPI_DMA 30 | csi_dma_init(&dma_hdl, 0); 31 | #endif 32 | 33 | } 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /cores/sg200x/Tone.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "Arduino.h" 6 | #include "common.h" 7 | #include "csi_gpio_pin.h" 8 | #include "csi_pin.h" 9 | #include "csi_pwm.h" 10 | #include "wiring_analog.h" 11 | #include "Tone.h" 12 | 13 | int channel = -1; 14 | static csi_pwm_t active_pwm; 15 | 16 | extern dev_pin_map_t pwm_map[]; 17 | 18 | void tone(pin_size_t pinNumber, unsigned int frequency) 19 | { 20 | const dev_pin_map_t* pwm_pin = target_pin_number_to_dev(pinNumber, pwm_map, 0xFF); 21 | 22 | if (pwm_pin == NULL) { 23 | pr_err("pin GPIO %d is not used as PWM func\n", pinNumber); 24 | return; 25 | } 26 | 27 | uint8_t pwm_idx = pwm_pin->idx >> 2; 28 | uint8_t pwm_channel = pwm_pin->idx & 0x3; 29 | 30 | if (csi_pin_set_mux(pwm_pin->name, pwm_pin->func)) { 31 | pr_err("pin GPIO %d fails to config as PWM func\n", pinNumber); 32 | return; 33 | }; 34 | 35 | if (channel != -1 && channel != pwm_channel) { 36 | return; 37 | } 38 | 39 | if (channel == -1) { 40 | csi_error_t ret_status = csi_pwm_init(&active_pwm, pwm_idx); 41 | if (ret_status != CSI_OK) { 42 | pr_err("GPIO pin %d init failed\n", pinNumber); 43 | return; 44 | } 45 | channel = pwm_channel; 46 | } 47 | 48 | csi_pwm_out_stop(&active_pwm, pwm_channel); 49 | 50 | csi_pwm_out_config_continuous(&active_pwm, pwm_channel, 1000 * 1000 / frequency, 51 | 1000 * 1000 / frequency / 2, PWM_POLARITY_LOW); 52 | 53 | csi_pwm_out_start(&active_pwm, pwm_channel); 54 | } 55 | 56 | void tone(pin_size_t pinNumber, unsigned int frequency, unsigned long duration) 57 | { 58 | const dev_pin_map_t* pwm_pin = target_pin_number_to_dev(pinNumber, pwm_map, 0xFF); 59 | 60 | if (pwm_pin == NULL) { 61 | pr_err("pin GPIO %d is not used as PWM func\n", pinNumber); 62 | return; 63 | } 64 | 65 | uint8_t pwm_idx = pwm_pin->idx >> 2; 66 | uint8_t pwm_channel = pwm_pin->idx & 0x3; 67 | 68 | if (csi_pin_set_mux(pwm_pin->name, pwm_pin->func)) { 69 | pr_err("pin GPIO %d fails to config as PWM func\n", pinNumber); 70 | return; 71 | }; 72 | 73 | if (channel != -1 && channel != pwm_channel) { 74 | return; 75 | } 76 | 77 | if (channel == -1) { 78 | csi_error_t ret_status = csi_pwm_init(&active_pwm, pwm_idx); 79 | if (ret_status != CSI_OK) { 80 | pr_err("GPIO pin %d init failed\n", pinNumber); 81 | return; 82 | } 83 | channel = pwm_channel; 84 | } 85 | 86 | csi_pwm_out_stop(&active_pwm, pwm_channel); 87 | 88 | csi_pwm_out_config_count(&active_pwm, pwm_channel, 1000 * 1000 / frequency, duration); 89 | csi_pwm_out_start(&active_pwm, pwm_channel); 90 | } 91 | 92 | void noTone(pin_size_t __attribute__((unused)) pin) 93 | { 94 | if (channel != -1) { 95 | csi_pwm_out_stop(&active_pwm, channel); 96 | channel = -1; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /cores/sg200x/WMath.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2022, Canaan Bright Sight Co., Ltd 3 | This file is modified from part of the k210 core for Arduino environment. 4 | */ 5 | 6 | #include "common.h" 7 | #include "csi_riscv_gcc.h" 8 | 9 | static bool maxed = false; 10 | static uint32_t pad = 0, n = 0, d = 0; 11 | static uint8_t dat = 0; 12 | 13 | static void set_seed(unsigned long seed) 14 | { 15 | maxed = true; 16 | pad = (uint32_t)(seed * csi_clint_get_value() & 0xFFFFFFFF); 17 | n = (uint32_t)(seed * csi_clint_get_value() & 0x12345678); 18 | d = (uint32_t)(seed * csi_clint_get_value() & 0x87654321); 19 | } 20 | 21 | static uint32_t get_random(void) 22 | { 23 | if (!maxed) { 24 | set_seed(1); 25 | } 26 | 27 | pad += dat + d * n; 28 | pad = (pad << 3) + (pad >> 29); 29 | n = pad | 2; 30 | d ^= (pad << 31) + (pad >> 1); 31 | dat ^= (char)pad ^ (d >> 8) ^ 1; 32 | 33 | return pad ^ (d << 5) ^ (pad >> 18) ^ (dat << 1); 34 | } 35 | 36 | 37 | void randomSeed(uint32_t seed) 38 | { 39 | set_seed(seed); 40 | get_random(); 41 | } 42 | 43 | long random(long max) 44 | { 45 | uint32_t x = get_random(); 46 | uint64_t m = uint64_t(x) * uint64_t(max); 47 | uint32_t l = uint32_t(m); 48 | if (l < max) { 49 | uint32_t t = -max; 50 | if (t >= max) { 51 | t -= max; 52 | if (t >= max) 53 | t %= max; 54 | } 55 | while (l < t) { 56 | x = get_random(); 57 | m = uint64_t(x) * uint64_t(max); 58 | l = uint32_t(m); 59 | } 60 | } 61 | return m >> 32; 62 | } 63 | 64 | long random(long min, long max) 65 | { 66 | if (min >= max) { 67 | return min; 68 | } 69 | long diff = max - min; 70 | return random(diff) + min; 71 | } 72 | 73 | long map(long x, long in_min, long in_max, long out_min, long out_max) 74 | { 75 | const long run = in_max - in_min; 76 | if (run == 0) { 77 | return -1; 78 | } 79 | const long rise = out_max - out_min; 80 | const long delta = x - in_min; 81 | return (delta * rise) / run + out_min; 82 | } 83 | 84 | uint16_t makeWord(uint16_t w) 85 | { 86 | return w; 87 | } 88 | 89 | uint16_t makeWord(uint8_t h, uint8_t l) 90 | { 91 | return (h << 8) | l; 92 | } 93 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/drivers/csi_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "csi_common.h" 6 | #include "csi_pin.h" 7 | 8 | extern pin_name_t out_pin_map[]; 9 | const dev_pin_map_t* target_pin_number_to_dev(uint8_t pin, const dev_pin_map_t *pinmap, uint8_t idx) 10 | { 11 | const dev_pin_map_t *map = pinmap; 12 | const dev_pin_map_t* ret = NULL; 13 | 14 | if (pin >= OUT_PIN_NUM) { 15 | return ret; 16 | } 17 | 18 | pin_name_t name = out_pin_map[pin]; 19 | 20 | while ((uint32_t)map->name != 0xFFFFFFFFU) { 21 | if ((map->name == name) && ((map->idx == idx) || (idx == 0xFF))) { 22 | ret = map; 23 | break; 24 | } 25 | 26 | map++; 27 | } 28 | 29 | return ret; 30 | } 31 | 32 | #define L1_CACHE_BYTES 64 33 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 34 | 35 | /* 36 | * dcache.ipa rs1 (invalidate) 37 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 38 | * 0000001 01010 rs1 000 00000 0001011 39 | * 40 | * dcache.cpa rs1 (clean) 41 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 42 | * 0000001 01001 rs1 000 00000 0001011 43 | * 44 | * dcache.cipa rs1 (clean then invalidate) 45 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 46 | * 0000001 01011 rs1 000 00000 0001011 47 | * 48 | * sync.s 49 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | 50 | * 0000000 11001 00000 000 00000 0001011 51 | */ 52 | #define DCACHE_IPA_A0 ".long 0x02a5000b" 53 | #define DCACHE_CPA_A0 ".long 0x0295000b" 54 | #define DCACHE_CIPA_A0 ".long 0x02b5000b" 55 | 56 | #define SYNC_S ".long 0x0190000b" 57 | 58 | #define CACHE_OP_RANGE(OP, start, size) \ 59 | register unsigned long i asm("a0") = start & ~(L1_CACHE_BYTES - 1); \ 60 | for (; i < ALIGN(start + size, L1_CACHE_BYTES); i += L1_CACHE_BYTES) \ 61 | __asm__ __volatile__(OP); \ 62 | __asm__ __volatile__(SYNC_S) 63 | 64 | //void c900_cache_invalidate(phys_addr_t start, size_t size) 65 | void inv_dcache_range(uintptr_t start, size_t size) 66 | { 67 | CACHE_OP_RANGE(DCACHE_IPA_A0, start, size); 68 | } 69 | 70 | //void c900_cache_clean(phys_addr_t start, size_t size) 71 | void clean_dcache_range(uintptr_t start, size_t size) 72 | { 73 | CACHE_OP_RANGE(DCACHE_CPA_A0, start, size); 74 | } 75 | 76 | //void c900_cache_flush(phys_addr_t start, size_t size) 77 | void flush_dcache_range(uintptr_t start, size_t size) 78 | { 79 | CACHE_OP_RANGE(DCACHE_CIPA_A0, start, size); 80 | } 81 | 82 | void enable_dcache(void) 83 | { 84 | asm volatile( 85 | "csrs 0x7c1, %0;" ::"rI"(0x2) 86 | ); 87 | } 88 | 89 | void disable_dcache(void) 90 | { 91 | asm volatile( 92 | "csrc 0x7c1, %0;" ::"rI"(0x2) 93 | ); 94 | } 95 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/drivers/csi_dma_consts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "csi_dma.h" 6 | 7 | const uint8_t g_dma_chnum[] = {16}; 8 | 9 | /* DMA handshake number */ 10 | /* The member of uart_tx_hs_num is the handshake number for ETB */ 11 | const uint16_t uart_tx_hs_num[] = {19}; 12 | const uint16_t uart_rx_hs_num[] = {18}; 13 | const uint16_t iic_tx_hs_num[] = {21, 23}; 14 | const uint16_t iic_rx_hs_num[] = {20, 22}; 15 | const uint16_t spi_tx_hs_num[] = {17, 19, 21, 23}; //TOFIX 16 | const uint16_t spi_rx_hs_num[] = {16, 18, 20, 22}; //TOFIX 17 | const uint16_t i2s_tx_hs_num[] = {9, 11, 13, 36, 37, 38, 39}; 18 | const uint16_t i2s_rx_hs_num[] = {8, 10, 12, 14, 15, 16, 17}; 19 | const uint16_t spdif_tx_hs_num[] = {25, 27}; 20 | const uint16_t spdif_rx_hs_num[] = {24, 26}; 21 | const uint16_t tdm_rx_hs_num[] = {28, 29, 30, 31, 32, 33, 34, 35}; 22 | const uint16_t vad_rx_hs_num[] = {0, 1, 2, 3, 4, 5, 6, 7}; 23 | 24 | const csi_dma_ch_desc_t uart0_dma_ch_list[] = { 25 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 26 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 27 | {0xff, 0xff} 28 | }; 29 | 30 | const csi_dma_ch_desc_t iic0_dma_ch_list[] = { 31 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 32 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 33 | {0xff, 0xff} 34 | }; 35 | 36 | const csi_dma_ch_desc_t iic1_dma_ch_list[] = { 37 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 38 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 39 | {0xff, 0xff} 40 | }; 41 | 42 | const csi_dma_ch_desc_t i2s0_dma_ch_list[] = { 43 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 44 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 45 | {0xff, 0xff} 46 | }; 47 | 48 | const csi_dma_ch_desc_t i2s1_dma_ch_list[] = { 49 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 50 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 51 | {0xff, 0xff} 52 | }; 53 | 54 | const csi_dma_ch_desc_t i2s2_dma_ch_list[] = { 55 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 56 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 57 | {0xff, 0xff} 58 | }; 59 | 60 | const csi_dma_ch_desc_t i2s3_dma_ch_list[] = { 61 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 62 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 63 | {0xff, 0xff} 64 | }; 65 | 66 | const csi_dma_ch_desc_t spdif0_dma_ch_list[] = { 67 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 68 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 69 | {0xff, 0xff} 70 | }; 71 | 72 | const csi_dma_ch_desc_t spdif1_dma_ch_list[] = { 73 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 74 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 75 | {0xff, 0xff} 76 | }; 77 | 78 | const csi_dma_ch_desc_t tdm_dma_ch_list[] = { 79 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 80 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 81 | {0xff, 0xff} 82 | }; 83 | 84 | const csi_dma_ch_desc_t vad_dma_ch_list[] = { 85 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 86 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 87 | {0xff, 0xff} 88 | }; 89 | 90 | const csi_dma_ch_desc_t spi3_dma_ch_list[] = { 91 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 92 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 93 | {0xff, 0xff} 94 | }; 95 | 96 | const csi_dma_ch_desc_t spi2_dma_ch_list[] = { 97 | {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 98 | {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, 99 | {0xff, 0xff} 100 | }; 101 | 102 | const csi_dma_ch_spt_list_t dma_spt_list[] = { 103 | {DEV_DW_UART_TAG, 0, uart0_dma_ch_list}, 104 | {DEV_DW_IIC_TAG, 0, iic0_dma_ch_list}, 105 | {DEV_DW_IIC_TAG, 1, iic1_dma_ch_list}, 106 | {DEV_WJ_I2S_TAG, 0, i2s0_dma_ch_list}, 107 | {DEV_WJ_I2S_TAG, 1, i2s1_dma_ch_list}, 108 | {DEV_WJ_I2S_TAG, 2, i2s2_dma_ch_list}, 109 | {DEV_WJ_I2S_TAG, 3, i2s3_dma_ch_list}, 110 | {DEV_WJ_SPDIF_TAG, 0, spdif0_dma_ch_list}, 111 | {DEV_WJ_SPDIF_TAG, 1, spdif1_dma_ch_list}, 112 | {DEV_WJ_TDM_TAG, 0, tdm_dma_ch_list}, 113 | {DEV_WJ_VAD_TAG, 0, vad_dma_ch_list}, 114 | {DEV_DW_SPI_TAG, 2, spi2_dma_ch_list}, /* spi2 */ 115 | {0xFFFFU, 0xFFU, NULL}, 116 | }; 117 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/drivers/csi_gpio_pin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | /****************************************************************************** 6 | * @file gpio_pin.c 7 | * @brief 8 | * @version 9 | * @date 2020-06-28 10 | ******************************************************************************/ 11 | #include 12 | 13 | #include "csi_gpio_pin.h" 14 | #include "csi_pin.h" 15 | #include "csi_riscv_gcc.h" 16 | #include "common.h" 17 | 18 | #include "dw_gpio_ll.h" 19 | 20 | csi_gpio_manage_t g_gpio_manage[CONFIG_GPIO_NUM]; 21 | 22 | extern csi_error_t csi_pin_mode(pin_name_t pin_name, csi_gpio_mode_t mode); 23 | 24 | static void gpio_manage_callback(csi_gpio_t *gpio, uint32_t pins, void *arg) 25 | { 26 | csi_gpio_pin_t **pin; 27 | uint8_t pin_idx = 0U; 28 | 29 | do { 30 | if (pins == 0U) { 31 | break ; 32 | } 33 | 34 | pin = &g_gpio_manage[gpio->dev.idx].pin[0]; 35 | 36 | do { 37 | while (!(pins & 0x1U)) { 38 | pins >>= 1U; 39 | pin_idx++; 40 | } 41 | 42 | if (pin[pin_idx] && pin[pin_idx]->callback) { 43 | pin[pin_idx]->callback(pin[pin_idx], pin[pin_idx]->arg); 44 | } 45 | 46 | pins >>= 1U; 47 | pin_idx++; 48 | } while (pins); 49 | } while (0); 50 | } 51 | 52 | csi_error_t csi_gpio_pin_init(csi_gpio_pin_t *pin, pin_name_t pin_name) 53 | { 54 | CSI_PARAM_CHK(pin, CSI_ERROR); 55 | 56 | csi_error_t ret = CSI_OK; 57 | size_t state; 58 | uint32_t idx; 59 | 60 | idx = csi_pin_get_gpio_channel(pin_name); 61 | 62 | if (idx == 0xFFFFFFFFU) { 63 | ret = CSI_ERROR; 64 | } else { 65 | pin->pin_idx = idx; 66 | } 67 | 68 | idx = csi_pin_get_gpio_devidx(pin_name); 69 | 70 | if (idx == 0xFFFFFFFFU) { 71 | ret = CSI_ERROR; 72 | } else { 73 | state = csi_irq_save(); 74 | 75 | if (!g_gpio_manage[idx].gpio.dev.reg_base) { 76 | csi_gpio_init(&g_gpio_manage[idx].gpio, idx); 77 | csi_gpio_attach_callback(&g_gpio_manage[idx].gpio, gpio_manage_callback, NULL); 78 | } 79 | 80 | csi_irq_restore(state); 81 | pin->gpio = &g_gpio_manage[idx].gpio; 82 | g_gpio_manage[idx].pin[pin->pin_idx] = pin; 83 | } 84 | 85 | return ret; 86 | } 87 | 88 | void csi_gpio_pin_uninit(csi_gpio_pin_t *pin) 89 | { 90 | CSI_PARAM_CHK_NORETVAL(pin); 91 | 92 | size_t state; 93 | 94 | for (uint8_t i = 0U; i < CONFIG_GPIO_NUM; i++) { 95 | state = csi_irq_save(); 96 | 97 | if (&g_gpio_manage[i].gpio == pin->gpio) { 98 | g_gpio_manage[i].pin[pin->pin_idx] = NULL; 99 | } 100 | 101 | csi_irq_restore(state); 102 | } 103 | 104 | pin->pin_idx = 0U; 105 | pin->callback = NULL; 106 | pin->arg = NULL; 107 | } 108 | 109 | csi_error_t csi_gpio_pin_attach_callback(csi_gpio_pin_t *pin, void *callback, void *arg) 110 | { 111 | CSI_PARAM_CHK(pin, CSI_ERROR); 112 | CSI_PARAM_CHK(callback, CSI_ERROR); 113 | 114 | uint32_t bitmask; 115 | 116 | dw_gpio_regs_t *reg = (dw_gpio_regs_t *)HANDLE_REG_BASE(pin->gpio); 117 | 118 | bitmask = dw_gpio_read_port_int_status(reg); 119 | 120 | /* clear all interrput */ 121 | dw_gpio_clr_port_irq(reg, bitmask); 122 | 123 | pin->callback = callback; 124 | pin->arg = arg; 125 | 126 | return CSI_OK; 127 | } 128 | 129 | csi_error_t csi_gpio_pin_dir(csi_gpio_pin_t *pin, csi_gpio_dir_t dir) 130 | { 131 | CSI_PARAM_CHK(pin, CSI_ERROR); 132 | 133 | return csi_gpio_dir(pin->gpio, (uint32_t)1U << pin->pin_idx, dir); 134 | } 135 | 136 | csi_error_t csi_gpio_pin_mode(csi_gpio_pin_t *pin, csi_gpio_mode_t mode) 137 | { 138 | CSI_PARAM_CHK(pin, CSI_ERROR); 139 | 140 | return csi_gpio_mode(pin->gpio, (uint32_t)1U << pin->pin_idx, mode); 141 | } 142 | 143 | csi_error_t csi_gpio_pin_irq_mode(csi_gpio_pin_t *pin, csi_gpio_irq_mode_t mode) 144 | { 145 | CSI_PARAM_CHK(pin, CSI_ERROR); 146 | 147 | return csi_gpio_irq_mode(pin->gpio, (uint32_t)1U << pin->pin_idx, mode); 148 | } 149 | 150 | csi_error_t csi_gpio_pin_irq_enable(csi_gpio_pin_t *pin, bool enable) 151 | { 152 | CSI_PARAM_CHK(pin, CSI_ERROR); 153 | 154 | return csi_gpio_irq_enable(pin->gpio, (uint32_t)1U << pin->pin_idx, enable); 155 | } 156 | 157 | csi_error_t csi_gpio_pin_debounce(csi_gpio_pin_t *pin, bool enable) 158 | { 159 | CSI_PARAM_CHK(pin, CSI_ERROR); 160 | 161 | return csi_gpio_debounce(pin->gpio, (uint32_t)1U << pin->pin_idx, enable); 162 | } 163 | 164 | void csi_gpio_pin_write(csi_gpio_pin_t *pin, csi_gpio_pin_state_t value) 165 | { 166 | CSI_PARAM_CHK_NORETVAL(pin); 167 | 168 | return csi_gpio_write(pin->gpio, (uint32_t)1U << pin->pin_idx, value); 169 | } 170 | 171 | void csi_gpio_pin_toggle(csi_gpio_pin_t *pin) 172 | { 173 | CSI_PARAM_CHK_NORETVAL(pin); 174 | 175 | return csi_gpio_toggle(pin->gpio, (uint32_t)1U << pin->pin_idx); 176 | } 177 | 178 | csi_gpio_pin_state_t csi_gpio_pin_read(csi_gpio_pin_t *pin) 179 | { 180 | csi_gpio_pin_state_t state; 181 | 182 | if (csi_gpio_read(pin->gpio, (uint32_t)1U << pin->pin_idx) != 0U) { 183 | state = GPIO_PIN_HIGH; 184 | } else { 185 | state = GPIO_PIN_LOW; 186 | } 187 | 188 | return state; 189 | } 190 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/drivers/cvi_mailbox.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | 3 | #include "common.h" 4 | #include "cvi_mailbox.h" 5 | #include "cvi_spinlock.h" 6 | 7 | DEFINE_CVI_SPINLOCK(mailbox_lock, SPIN_MBOX); 8 | 9 | void mailbox_init(); 10 | // void mailbox_register (int channel, void(*callback)(MailboxMsg)); 11 | // void mailbox_unregister (int channel); 12 | void mailbox_enable_receive(int channel); 13 | void mailbox_disable_receive(int channel); 14 | void mailbox_write(int channel, void *msg); 15 | 16 | int send_to_cpu = SEND_TO_CPU1; 17 | 18 | unsigned int reg_base = MAILBOX_REG_BASE; 19 | volatile struct mailbox_set_register *mbox_reg; 20 | volatile struct mailbox_done_register *mbox_done_reg; 21 | volatile unsigned int *mailbox_context; 22 | 23 | void mailbox_init() 24 | { 25 | int i; 26 | mbox_reg = (struct mailbox_set_register *)reg_base; 27 | mbox_done_reg = (struct mailbox_done_register *)(reg_base + 2); 28 | mailbox_context = (unsigned int *)(MAILBOX_REG_BUFF); 29 | 30 | for (i = 0; i < MAILBOX_MAX_NUM; i++) 31 | mailbox_context[i] = 0; 32 | } 33 | 34 | void mailbox_write(int channel, void *msg) 35 | { 36 | int valid; 37 | int flags; 38 | uint32_t *ptr; 39 | 40 | ptr = (uint32_t *)mailbox_context + (4 * channel); 41 | 42 | drv_spin_lock_irqsave(&mailbox_lock, flags); 43 | if (flags == MAILBOX_LOCK_FAILED) { 44 | return; 45 | } 46 | 47 | *ptr = (uint32_t *)msg; 48 | 49 | // clear mailbox 50 | mbox_reg->cpu_mbox_set[send_to_cpu].cpu_mbox_int_clr.mbox_int_clr = (1 << valid); 51 | // trigger mailbox valid to rtos 52 | mbox_reg->cpu_mbox_en[send_to_cpu].mbox_info |= (1 << valid); 53 | mbox_reg->mbox_set.mbox_set = (1 << valid); 54 | 55 | drv_spin_unlock_irqrestore(&mailbox_lock, flags); 56 | if (valid >= MAILBOX_MAX_NUM) { 57 | printf("No valid mailbox is available\n"); 58 | return -1; 59 | } 60 | } 61 | 62 | void mailbox_isr(void) 63 | { 64 | unsigned char set_val; 65 | int i; 66 | set_val = mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_int.mbox_int; 67 | unsigned char valid_val; 68 | 69 | uint32_t *msg; 70 | 71 | if (set_val) { 72 | for (i = 0; i < MAILBOX_MAX_NUM; i++) { 73 | valid_val = set_val & (1 << i); 74 | 75 | if (valid_val) { 76 | msg = (uint32_t *)mailbox_context + (4 * i); 77 | 78 | /* mailbox buffer context is send from linux, clear mailbox interrupt */ 79 | mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_clr.mbox_int_clr = valid_val; 80 | // need to disable enable bit 81 | mbox_reg->cpu_mbox_en[RECEIVE_CPU].mbox_info &= ~valid_val; 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/drivers/cvi_spinlock.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | 3 | #include "stdint.h" 4 | #include "csi_riscv_gcc.h" 5 | #include "cvi_spinlock.h" 6 | 7 | #define MAILBOX_REG_BASE 0x01900000 8 | #define MAILBOX_REG_BUFF (MAILBOX_REG_BASE + 0x0400) 9 | #define SPINLOCK_REG_BASE (MAILBOX_REG_BASE + 0x00c0) 10 | 11 | static unsigned long reg_base = SPINLOCK_REG_BASE; 12 | 13 | static unsigned char lockCount[SPIN_MAX + 1] = {0}; 14 | 15 | void cvi_spinlock_init() 16 | { 17 | } 18 | 19 | void cvi_spinlock_deinit(void) 20 | { 21 | } 22 | 23 | void spinlock_base(unsigned long mb_base) 24 | { 25 | reg_base = mb_base; 26 | } 27 | 28 | static inline int hw_spin_trylock(hw_raw_spinlock_t *lock) 29 | { 30 | writew(lock->locks, reg_base + sizeof(int) * lock->hw_field); 31 | if (readw(reg_base + sizeof(int) * lock->hw_field) == lock->locks) 32 | return MAILBOX_LOCK_SUCCESS; 33 | return MAILBOX_LOCK_FAILED; 34 | } 35 | 36 | int hw_spin_lock(hw_raw_spinlock_t *lock) 37 | { 38 | unsigned long i; 39 | unsigned long loops = 1000000; 40 | hw_raw_spinlock_t _lock = {.hw_field = lock->hw_field, .locks = lock->locks}; 41 | 42 | if (lockCount[lock->hw_field] == 0) { 43 | lockCount[lock->hw_field]++; 44 | } 45 | _lock.locks = (lockCount[lock->hw_field] << 8); 46 | lockCount[lock->hw_field]++; 47 | 48 | for (i = 0; i < loops; i++) { 49 | if (hw_spin_trylock(&_lock) == MAILBOX_LOCK_SUCCESS) { 50 | lock->locks = _lock.locks; 51 | return MAILBOX_LOCK_SUCCESS; 52 | } 53 | udelay(1); 54 | } 55 | 56 | return MAILBOX_LOCK_FAILED; 57 | } 58 | 59 | int _hw_raw_spin_lock_irqsave(hw_raw_spinlock_t *lock) 60 | { 61 | int flag = 0; 62 | 63 | // save and disable irq 64 | flag = (__get_MSTATUS() & 8); 65 | __disable_irq(); 66 | 67 | // lock 68 | if (hw_spin_lock(lock) == MAILBOX_LOCK_FAILED) { 69 | 70 | // if spinlock failed , restore irq 71 | if (flag) { 72 | __enable_irq(); 73 | } 74 | 75 | return MAILBOX_LOCK_FAILED; 76 | } 77 | return flag; 78 | } 79 | 80 | void _hw_raw_spin_unlock_irqrestore(hw_raw_spinlock_t *lock, int flag) 81 | { 82 | // unlock 83 | if (readw(reg_base + sizeof(int) * lock->hw_field) == lock->locks) { 84 | writew(lock->locks, reg_base + sizeof(int) * lock->hw_field); 85 | 86 | // restore irq 87 | if (flag) { 88 | __enable_irq(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/hal/dw/dw_iic_ll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #include 6 | #include "dw_iic_ll.h" 7 | #include "misc.h" 8 | 9 | uint32_t dw_iic_wait_for_bb(dw_iic_regs_t *iic_base) 10 | { 11 | uint16_t timeout = 0; 12 | while ((iic_base->IC_STATUS & DW_IIC_MST_ACTIVITY_STATE) || 13 | !(iic_base->IC_STATUS & DW_IIC_TXFIFO_EMPTY_STATE)) { 14 | 15 | /* Evaluate timeout */ 16 | delayMicroseconds(5); 17 | timeout++; 18 | if (timeout > 200) {/* exceed 1 ms */ 19 | pr_debug("Timed out waiting for bus busy\n"); 20 | return 1; 21 | } 22 | } 23 | 24 | return 0; 25 | } 26 | 27 | void dw_iic_set_reg_address(dw_iic_regs_t *iic_base, uint32_t addr, uint8_t addr_len) 28 | { 29 | while (addr_len) { 30 | addr_len--; 31 | /* high byte address going out first */ 32 | dw_iic_transmit_data(iic_base, (addr >> (addr_len * 8)) & 0xff); 33 | } 34 | } 35 | 36 | void dw_iic_set_target_address(dw_iic_regs_t *iic_base, uint32_t address) 37 | { 38 | uint32_t iic_status; 39 | iic_status = dw_iic_get_iic_status(iic_base); 40 | dw_iic_disable(iic_base); 41 | iic_base->IC_TAR = (iic_base->IC_TAR & ~0x3ff) | address; /* this register can be written only when the I2C is disabled*/ 42 | 43 | if (iic_status == DW_IIC_EN) { 44 | dw_iic_enable(iic_base); 45 | } 46 | } 47 | 48 | int32_t dw_iic_xfer_init(dw_iic_regs_t *iic_base, uint32_t dev_addr, 49 | uint16_t reg_addr, uint8_t reg_addr_len) 50 | { 51 | if (dw_iic_wait_for_bb(iic_base)) { 52 | return CSI_ERROR; 53 | } 54 | 55 | dw_iic_set_target_address(iic_base, dev_addr); 56 | dw_iic_enable(iic_base); 57 | dw_iic_set_reg_address(iic_base, reg_addr, reg_addr_len); 58 | 59 | return CSI_OK; 60 | } 61 | 62 | int32_t dw_iic_xfer_finish(dw_iic_regs_t *iic_base) 63 | { 64 | uint32_t timeout = 0; 65 | while (1) { 66 | if (iic_base->IC_RAW_INTR_STAT & DW_IIC_RAW_STOP_DET) { 67 | iic_base->IC_CLR_STOP_DET; 68 | break; 69 | } else { 70 | timeout++; 71 | delayMicroseconds(5); 72 | if (timeout > 1000000) { 73 | pr_debug("xfer finish tiemout\n"); 74 | break; 75 | } 76 | } 77 | } 78 | 79 | if (dw_iic_wait_for_bb(iic_base)) { 80 | return CSI_ERROR; 81 | } 82 | 83 | dw_iic_flush_rxfifo(iic_base); 84 | 85 | return CSI_OK; 86 | } 87 | 88 | void dw_iic_set_transfer_speed_high(dw_iic_regs_t *iic_base) 89 | { 90 | uint32_t speed_config = iic_base->IC_CON; 91 | speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN); 92 | speed_config |= DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN; 93 | iic_base->IC_CON = speed_config; 94 | } 95 | 96 | void dw_iic_set_transfer_speed_fast(dw_iic_regs_t *iic_base) 97 | { 98 | uint32_t speed_config = iic_base->IC_CON; 99 | speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN); 100 | speed_config |= DW_IIC_CON_SPEEDH_EN; 101 | iic_base->IC_CON = speed_config; 102 | } 103 | 104 | void dw_iic_set_transfer_speed_standard(dw_iic_regs_t *iic_base) 105 | { 106 | uint32_t speed_config = iic_base->IC_CON; 107 | speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN); 108 | speed_config |= DW_IIC_CON_SPEEDL_EN; 109 | iic_base->IC_CON = speed_config; 110 | } 111 | 112 | void dw_iic_set_slave_mode(dw_iic_regs_t *iic_base) 113 | { 114 | uint32_t iic_status; 115 | iic_status = dw_iic_get_iic_status(iic_base); 116 | dw_iic_disable(iic_base); 117 | uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN; 118 | iic_base->IC_CON &= ~val; ///< set 0 to disabled master mode; set 0 to enabled slave mode 119 | 120 | if (iic_status == DW_IIC_EN) { 121 | dw_iic_enable(iic_base); 122 | } 123 | } 124 | 125 | void dw_iic_set_master_mode(dw_iic_regs_t *iic_base) 126 | { 127 | uint32_t iic_status; 128 | iic_status = dw_iic_get_iic_status(iic_base); 129 | dw_iic_disable(iic_base); 130 | uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN; ///< set 1 to enabled master mode; set 1 to disabled slave mode 131 | iic_base->IC_CON |= val; 132 | 133 | if (iic_status == DW_IIC_EN) { 134 | dw_iic_enable(iic_base); 135 | } 136 | } 137 | 138 | uint32_t dw_iic_find_max_prime_num(uint32_t num) 139 | { 140 | uint32_t i = 0U; 141 | 142 | for (i = 8U; i > 0U; i --) { 143 | if (!num) { 144 | i = 1U; 145 | break; 146 | } 147 | 148 | if (!(num % i)) { 149 | break; 150 | } 151 | 152 | } 153 | 154 | return i; 155 | } 156 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/hal/dw/dw_spi_ll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #include "dw_spi_ll.h" 6 | 7 | void dw_spi_config_sclk_clock(dw_spi_regs_t *spi_base, uint32_t clock_in, uint32_t clock_out) 8 | { 9 | uint32_t div; 10 | 11 | div = clock_in / clock_out; 12 | div = (div > 65534U) ? 65534U : div; 13 | spi_base->BAUDR &= DW_SPI_BAUDR_SCKDV_Msk; 14 | spi_base->BAUDR = div; 15 | } 16 | 17 | uint32_t dw_spi_get_sclk_clock_div(dw_spi_regs_t *spi_base) 18 | { 19 | return spi_base->BAUDR; 20 | } 21 | 22 | uint32_t dw_spi_get_data_frame_len(dw_spi_regs_t *spi_base) 23 | { 24 | uint32_t len = spi_base->CTRLR0 & DW_SPI_CTRLR0_DFS_Msk; 25 | len >>= DW_SPI_CTRLR0_DFS_Pos; 26 | len++; 27 | return len; 28 | } 29 | 30 | void dw_spi_config_data_frame_len(dw_spi_regs_t *spi_base, uint32_t size) 31 | { 32 | uint32_t temp; 33 | 34 | if ((size >= 4U) & (size <= 16U)) { 35 | temp = spi_base->CTRLR0; 36 | temp &= ~DW_SPI_CTRLR0_DFS_Msk; 37 | temp |= ((size - 1U) << DW_SPI_CTRLR0_DFS_Pos); 38 | spi_base->CTRLR0 = temp; 39 | } 40 | } 41 | 42 | void dw_spi_reset_regs(dw_spi_regs_t *spi_base) 43 | { 44 | spi_base->CTRLR0 = 7U; 45 | spi_base->CTRLR1 = 0U; 46 | spi_base->SSIENR = 0U; 47 | spi_base->SER = 0U; 48 | spi_base->BAUDR = 0U; 49 | spi_base->TXFTLR = 0x10U; 50 | spi_base->RXFTLR = 0x10U; 51 | spi_base->IMR = 0x00U; 52 | spi_base->SPIMSSEL = 0x1U; 53 | } 54 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/hal/dw/dw_uart_ll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "dw_uart_ll.h" 6 | 7 | int32_t dw_uart_wait_idle(dw_uart_regs_t *uart_base) 8 | { 9 | uint32_t timecount = 0U; 10 | int32_t ret = 0; 11 | 12 | while ((uart_base->USR & DW_UART_USR_BUSY_SET) && (timecount < UART_BUSY_TIMEOUT)) { 13 | timecount++; 14 | } 15 | 16 | if (timecount >= UART_BUSY_TIMEOUT) { 17 | ret = -1; 18 | } 19 | 20 | return ret; 21 | } 22 | 23 | int32_t dw_uart_wait_timeout(dw_uart_regs_t *uart_base) 24 | { 25 | uint32_t timecount = 0U; 26 | int32_t ret = 0; 27 | 28 | while ((uart_base->LSR & 0x81U) || (uart_base->USR & 0x1U)) { 29 | uart_base->LSR; 30 | uart_base->RBR; 31 | timecount++; 32 | 33 | if (timecount >= UART_BUSY_TIMEOUT) { 34 | ret = -1; 35 | break; 36 | } 37 | } 38 | 39 | if (ret == 0) { 40 | ret = dw_uart_wait_idle(uart_base); 41 | } 42 | 43 | return ret; 44 | } 45 | 46 | int32_t dw_uart_config_baudrate(dw_uart_regs_t *uart_base, uint32_t baud, uint32_t uart_freq) 47 | { 48 | uint32_t divisor; 49 | int32_t ret = 0; 50 | ret = dw_uart_wait_timeout(uart_base); 51 | 52 | if (ret == 0) { 53 | divisor = (uart_freq / 16) / baud; 54 | //divisor = ((UART_SCLK * 10) / baud) >> 4; 55 | 56 | uart_base->LCR |= DW_UART_LCR_DLAB_EN; 57 | 58 | /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/ 59 | uart_base->DLH = (divisor >> 8U) & 0xFFU; 60 | uart_base->DLL = divisor & 0xFFU; 61 | /* 62 | * The DLAB must be cleared after the baudrate is setted 63 | * to access other registers. 64 | */ 65 | uart_base->LCR &= (~DW_UART_LCR_DLAB_EN); 66 | } 67 | 68 | return ret; 69 | } 70 | 71 | int32_t dw_uart_config_stop_bits(dw_uart_regs_t *uart_base, uint32_t stop_bits) 72 | { 73 | int32_t ret; 74 | ret = dw_uart_wait_timeout(uart_base); 75 | 76 | if (ret == 0) { 77 | 78 | //when data length is 5 bits, use dw_uart_config_stop_bits_2 will be 1.5 stop bits 79 | if (stop_bits == 1U) { 80 | dw_uart_config_stop_bits_1(uart_base); 81 | } else if (stop_bits == 2U) { 82 | dw_uart_config_stop_bits_2(uart_base); 83 | } 84 | } 85 | 86 | return ret; 87 | } 88 | 89 | int32_t dw_uart_config_parity_none(dw_uart_regs_t *uart_base) 90 | { 91 | int32_t ret; 92 | ret = dw_uart_wait_timeout(uart_base); 93 | 94 | if (ret == 0) { 95 | uart_base->LCR &= (~DW_UART_LCR_PEN_EN); 96 | } 97 | 98 | return ret; 99 | } 100 | 101 | int32_t dw_uart_config_parity_odd(dw_uart_regs_t *uart_base) 102 | { 103 | int32_t ret; 104 | 105 | ret = dw_uart_wait_timeout(uart_base); 106 | 107 | if (ret == 0) { 108 | uart_base->LCR |= DW_UART_LCR_PEN_EN; 109 | uart_base->LCR &= ~(DW_UART_LCR_EPS_EN); 110 | } 111 | 112 | return ret; 113 | } 114 | 115 | int32_t dw_uart_config_parity_even(dw_uart_regs_t *uart_base) 116 | { 117 | int32_t ret; 118 | 119 | ret = dw_uart_wait_timeout(uart_base); 120 | 121 | if (ret == 0) { 122 | uart_base->LCR |= DW_UART_LCR_PEN_EN; 123 | uart_base->LCR |= DW_UART_LCR_EPS_EN; 124 | } 125 | 126 | return ret; 127 | } 128 | 129 | int32_t dw_uart_config_data_bits(dw_uart_regs_t *uart_base, uint32_t data_bits) 130 | { 131 | int32_t ret; 132 | 133 | ret = dw_uart_wait_timeout(uart_base); 134 | 135 | uart_base->LCR &= 0xFCU; 136 | uart_base->LCR |= (data_bits - 5U); 137 | 138 | return ret; 139 | } 140 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/hal/hal_dma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "hal_dma.h" 6 | #include "common.h" 7 | #include "mmio.h" 8 | 9 | void hal_dma_ch_resume(struct dw_dma *dma, uint8_t ch_mask); 10 | void hal_dma_dwc_clk_set(int enable) 11 | { 12 | uint32_t clk_state; 13 | 14 | clk_state = mmio_read_32((long unsigned int)DMA_CLK_EN_REG); 15 | 16 | if (enable) 17 | clk_state |= 1 << CLK_SDMA_AXI_BIT; 18 | else 19 | clk_state &= ~(1 << CLK_SDMA_AXI_BIT); 20 | 21 | mmio_write_32((long unsigned int)DMA_CLK_EN_REG, clk_state); 22 | } 23 | 24 | void hal_dma_off(dw_dma_t *dma) 25 | { 26 | dma_writeq(dma, CFG, 0); /* disable dmac and interrupt */ 27 | while (dma_readq(dma, CFG) & 3) 28 | barrier(); 29 | } 30 | 31 | void hal_dma_on(dw_dma_t *dma) 32 | { 33 | dma_writeq(dma, CFG, DW_CFG_DMA_EN | DW_CFG_DMA_INT_EN); 34 | } 35 | 36 | void hal_dma_write_cfg(dw_dma_channel_t *dwc, uint64_t cfg) 37 | { 38 | channel_writeq(dwc, CFG, cfg); 39 | } 40 | 41 | void hal_dma_enable_irq(dw_dma_channel_t *dwc, uint64_t int_status_reg) 42 | { 43 | channel_writeq(dwc, INTSTATUS_ENABLEREG, int_status_reg); 44 | channel_writeq(dwc, INTSIGNAL_ENABLEREG, int_status_reg); 45 | } 46 | 47 | void hal_dma_write_llp(dw_dma_channel_t *dwc, uint64_t llp) 48 | { 49 | channel_writeq(dwc, LLP, llp); 50 | } 51 | 52 | uint64_t hal_dma_get_ch_en_status(struct dw_dma *dma) 53 | { 54 | return dma_readq(dma, CH_EN); 55 | } 56 | 57 | void hal_dma_ch_on(struct dw_dma *dma, uint8_t ch_mask) 58 | { 59 | uint64_t ch_en; 60 | 61 | ch_en = dma_readq(dma, CH_EN); 62 | ch_en |= (ch_mask << DW_DMAC_CH_EN_WE_OFFSET) | ch_mask; 63 | dma_writeq(dma, CH_EN, ch_en); 64 | } 65 | 66 | void hal_dma_ch_off(struct dw_dma *dma, uint8_t ch_mask) 67 | { 68 | uint64_t dma_ch_en; 69 | dma_ch_en = dma_readq(dma, CH_EN); 70 | if (dma_ch_en & (1 << (__ffs(ch_mask) + DW_DMAC_CH_PAUSE_OFFSET))) 71 | hal_dma_ch_resume(dma, ch_mask); 72 | dma_ch_en |= (ch_mask << DW_DMAC_CH_EN_WE_OFFSET); 73 | dma_ch_en &= ~ch_mask; 74 | dma_writeq(dma, CH_EN, dma_ch_en); 75 | //while (dma_readq(dma, CH_EN) & ch_mask) 76 | // barrier(); 77 | } 78 | 79 | void hal_dma_ch_pause(struct dw_dma *dma, uint8_t ch_mask) 80 | { 81 | unsigned int count = 20; /* timeout iterations */ 82 | uint64_t mask = ch_mask; 83 | 84 | dma_set_bit(dma, CH_EN, 85 | (1 << (__ffs(mask) + DW_DMAC_CH_PAUSE_OFFSET)) 86 | | (1 << (__ffs(mask) + DW_DMAC_CH_PAUSE_EN_OFFSET))); 87 | 88 | while (!(dma_readq(dma, CH_EN) 89 | & (1 << (__ffs(ch_mask) + DW_DMAC_CH_PAUSE_OFFSET))) 90 | && count--) 91 | delayMicroseconds(2); 92 | 93 | } 94 | 95 | void hal_dma_ch_resume(struct dw_dma *dma, uint8_t ch_mask) 96 | { 97 | uint64_t mask = ch_mask; 98 | uint64_t dma_ch_en; 99 | 100 | dma_ch_en = dma_readq(dma, CH_EN); 101 | dma_ch_en |= (mask << DW_DMAC_CH_EN_WE_OFFSET); 102 | dma_ch_en |= (1 << (__ffs(mask) + DW_DMAC_CH_PAUSE_EN_OFFSET)); 103 | dma_ch_en &= ~(1 << (__ffs(mask) + DW_DMAC_CH_PAUSE_OFFSET)); 104 | dma_writeq(dma,CH_EN,dma_ch_en); 105 | } 106 | 107 | uint64_t hal_dma_get_intstatus(dw_dma_t *dma) 108 | { 109 | return dma_readq(dma, INTSTATUS); 110 | } 111 | 112 | void hal_dma_clear_comm_intstatus(dw_dma_t *dma) 113 | { 114 | dma_writeq(dma, COMM_INTCLEAR, 0x10f); 115 | } 116 | 117 | /* return dwc status */ 118 | uint64_t hal_dma_dwc_read_clear_intstatus(dw_dma_channel_t *dwc) 119 | { 120 | uint64_t dwc_status; 121 | 122 | dwc_status = channel_readq(dwc, INTSTATUS); 123 | dma_dbg("channel, intstatus = %lx\r\n", dwc_status); 124 | channel_writeq(dwc, INTCLEARREG, dwc_status); 125 | 126 | return dwc_status; 127 | } 128 | 129 | void hal_dma_dwc_clear_intstatus(dw_dma_channel_t *dwc) 130 | { 131 | channel_writeq(dwc, INTCLEARREG, 0xffffffff); 132 | } 133 | 134 | void hal_dma_turn_off_chans(dw_dma_t *dma) 135 | { 136 | dma_set_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_EN_WE_OFFSET); 137 | dma_set_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_PAUSE_EN_OFFSET); 138 | dma_set_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_ABORT_EN_OFFSET); 139 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK); 140 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_PAUSE_OFFSET); 141 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_ABORT_OFFSET); 142 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_EN_WE_OFFSET); 143 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_PAUSE_EN_OFFSET); 144 | dma_clear_bit(dma, CH_EN, (uint64_t)DW_DMA_CHAN_MASK << DW_DMAC_CH_ABORT_EN_OFFSET); 145 | } 146 | 147 | void hal_dma_reset(dw_dma_t *dma) 148 | { 149 | dma_writeq(dma, RESET, 1); 150 | } 151 | 152 | void hal_sdma_dma_int_mux_set_c906b(void) 153 | { 154 | *(volatile uint32_t *)SDMA_DMA_INT_MUX = SDMA_DMA_INT_MUX_C906B; 155 | } 156 | 157 | void hal_sdma_dma_int_mux_set_c906l(void) 158 | { 159 | *(volatile uint32_t *)SDMA_DMA_INT_MUX = SDMA_DMA_INT_MUX_C906L; 160 | } 161 | 162 | /* ---------------------- show debug info -------------------------- */ 163 | void hal_print_dma_reg(struct dw_dma *dw) 164 | { 165 | dma_log("CFG: 0x%lx, CH_EN=0x%lx, INT_STATUS=0x%lx, COMM_INTSTATUS=0x%lx\r\n", 166 | dma_readq(dw, CFG), dma_readq(dw, CH_EN), dma_readq(dw, INTSTATUS), dma_readq(dw, COMM_INTSTATUS)); 167 | } 168 | 169 | void hal_print_ch_info(struct dw_dma *dw, int ch_id) 170 | { 171 | struct dw_dma_channel *dwc = &dw->chans[ch_id]; 172 | 173 | dma_dbg("SAR=%p\r\n", &(_dwc_regs(dwc)->SAR)); 174 | 175 | dma_log("Ch%d - SAR:0x%lx DAR:0x%lx ch_status:0x%lx int_status:0x%lx\r\n", ch_id, 176 | channel_readq(dwc, SAR), channel_readq(dwc, DAR), 177 | channel_readq(dwc, STATUS), channel_readq(dwc, INTSTATUS)); 178 | 179 | dma_log("\tLLP:0x%lx\r\n", channel_readq(dwc, LLP)); 180 | } 181 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/hal/hal_sysdma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "hal_sysdma.h" 6 | 7 | static struct dma_remap_item remap_table[] = { 8 | {CVI_UART2_TX, 1}, //13 9 | {CVI_UART2_RX, 0}, //13 10 | {CVI_I2S3_TX, 2}, //13 11 | {CVI_I2S0_RX, 3}, //13 12 | {CVI_SPI2_RX, 4}, 13 | {CVI_SPI2_TX, 5}, 14 | {CVI_I2S1_RX, 6}, 15 | {CVI_SPI_NAND, 7} 16 | 17 | }; 18 | 19 | static uint32_t remap0_val; 20 | static uint32_t remap1_val; 21 | 22 | static void dma_hs_remap(request_index_t hs_id, uint8_t channel_id) 23 | { 24 | if (channel_id < 4) { 25 | remap0_val |= hs_id << (channel_id << 3); 26 | } else { 27 | channel_id -= 4; 28 | remap1_val |= hs_id << (channel_id << 3); 29 | } 30 | } 31 | 32 | void hal_dma_hs_remap_init(void) 33 | { 34 | int table_size = sizeof(remap_table) / sizeof(struct dma_remap_item); 35 | 36 | for (int i = 0; i < table_size; i++) { 37 | dma_hs_remap(remap_table[i].hs_id, remap_table[i].channel_id); 38 | } 39 | 40 | remap0_val |= 1 << 31; 41 | remap1_val |= 1 << 31; 42 | 43 | *((volatile uint32_t *)REG_SDMA_DMA_CH_REMAP0) = remap0_val; 44 | *((volatile uint32_t *)REG_SDMA_DMA_CH_REMAP1) = remap1_val; 45 | 46 | //printf("remap0=%x\r\n", *((volatile uint32_t *)REG_SDMA_DMA_CH_REMAP0)); 47 | //printf("remap1=%x\r\n", *((volatile uint32_t *)REG_SDMA_DMA_CH_REMAP1)); 48 | } 49 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/csi/csi_gpio_pin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #ifndef _DRV_GPIO_PIN_H_ 6 | #define _DRV_GPIO_PIN_H_ 7 | 8 | #include 9 | #include 10 | #include "csi_gpio.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | * \struct csi_gpio_pin_t 18 | * \brief GPIO PIN control block 19 | */ 20 | 21 | typedef struct csi_gpio_pin csi_gpio_pin_t; 22 | struct csi_gpio_pin { 23 | csi_gpio_t *gpio; 24 | uint32_t pin_idx; 25 | void (*callback)(csi_gpio_pin_t *pin, void *arg); 26 | void *arg; 27 | }; 28 | 29 | typedef struct { 30 | csi_gpio_t gpio; 31 | csi_gpio_pin_t *pin[32]; 32 | } csi_gpio_manage_t; 33 | 34 | /** 35 | \brief Initialize GPIO pin handle 36 | \param[in] pin GPIO pin handle 37 | \param[in] pin_name GPIO pin name 38 | \return Error code 39 | */ 40 | csi_error_t csi_gpio_pin_init(csi_gpio_pin_t *pin, pin_name_t pin_name); 41 | 42 | /** 43 | \brief De-initialize GPIO pin 44 | \param[in] pin GPIO pin handle 45 | \return None 46 | */ 47 | void csi_gpio_pin_uninit(csi_gpio_pin_t *pin); 48 | 49 | /** 50 | \brief Attach the interrupt callback to the GPIO pin 51 | \param[in] pin GPIO pin handle 52 | \param[in] callback Callback function 53 | \param[in] arg User param passed to callback 54 | \return Error code 55 | */ 56 | csi_error_t csi_gpio_pin_attach_callback(csi_gpio_pin_t *pin, void *callback, void *arg); 57 | 58 | /** 59 | \brief Config pin direction 60 | \param[in] pin GPIO pin handle 61 | \param[in] dir \ref csi_gpio_dir_t 62 | \return Error code 63 | */ 64 | csi_error_t csi_gpio_pin_dir(csi_gpio_pin_t *pin, csi_gpio_dir_t dir); 65 | 66 | /** 67 | \brief Config pin mode 68 | \param[in] pin GPIO pin handle 69 | \param[in] mode \ref csi_gpio_mode_t 70 | \return Error code 71 | */ 72 | csi_error_t csi_gpio_pin_mode(csi_gpio_pin_t *pin, csi_gpio_mode_t mode); 73 | 74 | /** 75 | \brief Config pin irq params 76 | \param[in] pin GPIO pin handle 77 | \param[in] mode Interrupt trigger mode \ref csi_gpio_irq_mode_t 78 | \return Error code 79 | */ 80 | csi_error_t csi_gpio_pin_irq_mode(csi_gpio_pin_t *pin, csi_gpio_irq_mode_t mode); 81 | 82 | /** 83 | \brief Enable or disable gpio pin interrupt 84 | \param[in] pin GPIO pin handle 85 | \param[in] enable 0:disable 1:enable 86 | \return Error code 87 | */ 88 | csi_error_t csi_gpio_pin_irq_enable(csi_gpio_pin_t *pin, bool enable); 89 | 90 | /** 91 | \brief Set debounce of pin when pin configed as input 92 | \param[in] pin GPIO pin handle 93 | \param[in] enbale 0: disable 1:enable 94 | \return Error code 95 | */ 96 | csi_error_t csi_gpio_pin_debounce(csi_gpio_pin_t *pin, bool enable); 97 | 98 | /** 99 | \brief Set one or zero to specified pin 100 | \param[in] pin GPIO pin handle 101 | \param[in] value Value to be set \ref csi_gpio_pin_state_t 102 | \return None 103 | */ 104 | void csi_gpio_pin_write(csi_gpio_pin_t *pin, csi_gpio_pin_state_t value); 105 | 106 | /** 107 | \brief Toggle output pin value,ex.if previous value is 1, then output 0 108 | \param[in] pin GPIO pin handle 109 | \return None 110 | */ 111 | void csi_gpio_pin_toggle(csi_gpio_pin_t *pin); 112 | 113 | /** 114 | \brief Get the value of specified GPIO pin 115 | \param[in] pin GPIO port handle 116 | \return gpio pin state, \ref csi_gpio_pin_state_t 117 | */ 118 | csi_gpio_pin_state_t csi_gpio_pin_read(csi_gpio_pin_t *pin); 119 | 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | 124 | #endif /* _GPIO_PIN_H_*/ 125 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/csi/csi_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #ifndef _DRV_PWM_H_ 6 | #define _DRV_PWM_H_ 7 | 8 | #include "csi_common.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef enum { 15 | PWM_POLARITY_HIGH = 0U, ///< High level 16 | PWM_POLARITY_LOW ///< Low level 17 | } csi_pwm_polarity_t; 18 | 19 | typedef enum { 20 | PWM_MODE_CONTINUE = 0U, ///< continuous mode 21 | PWM_MODE_COUNT ///< pulse count mode 22 | } csi_pwm_mode_t; 23 | 24 | typedef enum { 25 | PWM_CAPTURE_POLARITY_POSEDGE = 0U, ///< Posedge Edge 26 | PWM_CAPTURE_POLARITY_NEGEDGE, ///< Negedge Edge 27 | PWM_CAPTURE_POLARITY_BOTHEDGE ///< Both Edge 28 | } csi_pwm_capture_polarity_t; 29 | 30 | typedef enum { 31 | PWM_EVENT_CAPTURE_POSEDGE = 0U, ///< Capture Posedge Event 32 | PWM_EVENT_CAPTURE_NEGEDGE, ///< Capture Negedge Event 33 | PWM_EVENT_CAPTURE_BOTHEDGE, ///< Capture Bothedge Event 34 | PWM_EVENT_ERROR, ///< Error 35 | } csi_pwm_event_t; 36 | 37 | typedef struct csi_pwm csi_pwm_t; 38 | 39 | struct csi_pwm { 40 | csi_dev_t dev; 41 | void (*callback)(csi_pwm_t *pwm, csi_pwm_event_t event, uint32_t ch, uint32_t time_us, void *arg); 42 | void *arg; 43 | void *priv; 44 | }; 45 | 46 | /** 47 | \brief Initialize PWM interface. Initializes the resources needed for the PWM interface 48 | \param[in] pwm Handle to operate 49 | \param[in] idx PWM idx 50 | \return Error code \ref csi_error_t 51 | */ 52 | csi_error_t csi_pwm_init(csi_pwm_t *pwm, uint32_t idx); 53 | 54 | /** 55 | \brief De-initialize PWM interface. Stops operation and releases the software resources used by the interface 56 | \param[in] pwm Handle to operate 57 | \return None 58 | */ 59 | void csi_pwm_uninit(csi_pwm_t *pwm); 60 | 61 | /** 62 | \brief Config PWM out mode 63 | \param[in] pwm Handle to operate 64 | \param[in] channel Channel num 65 | \param[in] period_us The PWM period in us 66 | \param[in] pulse_width_us The PMW pulse width in us 67 | \param[in] polarity The PWM polarity \ref csi_pwm_polarity_t 68 | \return Error code \ref csi_error_t 69 | */ 70 | csi_error_t csi_pwm_out_config_continuous(csi_pwm_t *pwm, 71 | uint32_t channel, 72 | uint32_t period_us, 73 | uint32_t pulse_width_us, 74 | csi_pwm_polarity_t polarity); 75 | 76 | csi_error_t csi_pwm_out_config_count(csi_pwm_t *pwm, 77 | uint32_t channel, 78 | uint32_t period_us, 79 | uint64_t pcount); 80 | 81 | /** 82 | \brief Start generate PWM signal 83 | \param[in] pwm Handle to operate 84 | \param[in] channel Channel num 85 | \return Error code \ref csi_error_t 86 | */ 87 | csi_error_t csi_pwm_out_start(csi_pwm_t *pwm, uint32_t channel); 88 | 89 | /** 90 | \brief Stop generate PWM signal 91 | \param[in] pwm Handle to operate 92 | \param[in] channel Channel num 93 | \return None 94 | */ 95 | void csi_pwm_out_stop(csi_pwm_t *pwm, uint32_t channel); 96 | 97 | /** 98 | \brief Config PWM capture mode 99 | \param[in] pwm Handle to operate 100 | \param[in] channel Channel num 101 | \param[in] polarity PWM capture polarity \ref csi_pwm_capture_polarity_t 102 | \param[in] count PWM capture polarity count 103 | \return Error code \ref csi_error_t 104 | */ 105 | csi_error_t csi_pwm_capture_config(csi_pwm_t *pwm, 106 | uint32_t channel, 107 | csi_pwm_capture_polarity_t polarity, 108 | uint32_t count); 109 | 110 | /** 111 | \brief Start PWM capture 112 | \param[in] pwm Handle to operate 113 | \param[in] channel Channel num 114 | \return Error code \ref csi_error_t 115 | */ 116 | csi_error_t csi_pwm_capture_start(csi_pwm_t *pwm, uint32_t channel); 117 | 118 | /** 119 | \brief Stop PWM capture 120 | \param[in] pwm Handle to operate 121 | \param[in] channel Channel num 122 | \return None 123 | */ 124 | void csi_pwm_capture_stop(csi_pwm_t *pwm, uint32_t channel); 125 | 126 | /** 127 | \brief Attach PWM callback 128 | \param[in] pwm Handle to operate 129 | \param[in] callback Callback func 130 | \param[in] arg Callback's param 131 | \return Error code \ref csi_error_t 132 | */ 133 | csi_error_t csi_pwm_attach_callback(csi_pwm_t *pwm, void *callback, void *arg); 134 | 135 | /** 136 | \brief Detach PWM callback 137 | \param[in] pwm Handle to operate 138 | \return None 139 | */ 140 | void csi_pwm_detach_callback(csi_pwm_t *pwm); 141 | 142 | /** 143 | \brief Enable PWM power manage 144 | \param[in] pwm Handle to operate 145 | \return Error code \ref csi_error_t 146 | */ 147 | csi_error_t csi_pwm_enable_pm(csi_pwm_t *pwm); 148 | 149 | /** 150 | \brief Disable PWM power manage 151 | \param[in] pwm Handle to operate 152 | \return None 153 | */ 154 | void csi_pwm_disable_pm(csi_pwm_t *pwm); 155 | 156 | #ifdef __cplusplus 157 | } 158 | #endif 159 | 160 | #endif /* _DRV_PWM_H_ */ 161 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/csi/csi_riscv_gcc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2019 Alibaba Group Holding Limited 3 | */ 4 | 5 | #ifndef _CSI_RV64_GCC_H_ 6 | #define _CSI_RV64_GCC_H_ 7 | 8 | #include "common.h" 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /** 14 | \brief Get MSTATUS 15 | \details Returns the content of the MSTATUS Register. 16 | \return MSTATUS Register value 17 | */ 18 | __ALWAYS_STATIC_INLINE uint64_t __get_MSTATUS(void) 19 | { 20 | uint64_t result; 21 | 22 | __ASM volatile("csrr %0, mstatus" : "=r"(result)); 23 | return (result); 24 | } 25 | 26 | /** 27 | \brief Set MSTATUS 28 | \details Writes the given value to the MSTATUS Register. 29 | \param [in] mstatus MSTATUS Register value to set 30 | */ 31 | __ALWAYS_STATIC_INLINE void __set_MSTATUS(uint64_t mstatus) 32 | { 33 | __ASM volatile("csrw mstatus, %0" : : "r"(mstatus)); 34 | } 35 | 36 | /** 37 | \brief Disable IRQ Interrupts 38 | \details Disables IRQ interrupts by clearing the IE-bit in the PSR. 39 | Can only be executed in Privileged modes. 40 | */ 41 | __ALWAYS_STATIC_INLINE void __disable_irq(void) 42 | { 43 | __ASM volatile("csrc mstatus, 8"); 44 | } 45 | 46 | /* ################################## IRQ Functions ############################################ */ 47 | 48 | /** 49 | \brief Save the Irq context 50 | \details save the psr result before disable irq. 51 | */ 52 | __STATIC_INLINE uint64_t csi_irq_save(void) 53 | { 54 | uint64_t result; 55 | result = __get_MSTATUS(); 56 | __disable_irq(); 57 | return (result); 58 | } 59 | 60 | /** 61 | \brief Restore the Irq context 62 | \details restore saved primask state. 63 | \param [in] irq_state psr irq state. 64 | */ 65 | __STATIC_INLINE void csi_irq_restore(uint64_t irq_state) 66 | { 67 | __set_MSTATUS(irq_state); 68 | } 69 | 70 | /*@} end of IRQ Functions */ 71 | 72 | /** 73 | \brief get CORE timer counter value 74 | \return CORE timer counter value. 75 | */ 76 | static inline uint64_t csi_clint_get_value(void) 77 | { 78 | uint64_t result; 79 | __asm volatile("csrr %0, 0xc01" : "=r"(result)); 80 | return result; 81 | } 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif /* _CSI_RV64_GCC_H_ */ 88 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/cvi/cvi_dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef __CVI_DMA_H__ 6 | #define __CVI_DMA_H__ 7 | 8 | #include "hal_dma.h" 9 | 10 | typedef struct { 11 | uint8_t ctrl_idx; 12 | uint8_t ch_idx; 13 | } cvi_dma_ch_desc_t; 14 | 15 | int cvi_dma_init(dw_dma_t *dma, int8_t ctrl_id, unsigned long reg_base, uint32_t irq_num); 16 | void cvi_dma_uninit(dw_dma_t *dma); 17 | int cvi_dma_ch_alloc(uint8_t ctrl_idx, uint8_t ch_idx); 18 | void cvi_dma_ch_stop(int ctrl_idx, int ch_idx); 19 | void cvi_dma_ch_free(int ctrl_idx, int ch_idx); 20 | void cvi_dma_ch_pause(int ctrl_idx, int ch_idx); 21 | void cvi_dma_ch_resume(int ctrl_idx, int ch_idx); 22 | int cvi_dma_ch_config(int ctrl_idx, int ch_idx, struct dw_dma_cfg *dw_cfg); 23 | void cvi_dma_ch_start(int ctrl_idx, int ch_idx, void *srcaddr, void *dstaddr, uint32_t length); 24 | uint32_t cvi_dma_get_inited_num(); 25 | uint32_t cvi_get_alloc_status_irqsave(uint8_t ctrl_idx, uint32_t *alloc_status); 26 | void cvi_release_alloc_status_irqrestore(uint32_t irq_flags); 27 | int cvi_dma_lock_ch(uint8_t ctrl_idx, uint8_t ch_idx); 28 | void _cvi_dma_ch_alloc(uint8_t ctrl_idx, uint8_t ch_idx); 29 | int cvi_set_ch_hw_param(dw_dma_channel_t *dwc, uint8_t master, uint8_t hs_polarity); 30 | void dma_show_info(); 31 | void dma_show_ch_info_all(); 32 | void dma_show_ch_info(int ch_id); 33 | void cvi_dma_ch_attach_callback(int ctrl_idx, int ch_idx, void *callback, void *args); 34 | void cvi_dma_ch_detach_callback(int ctrl_idx, int ch_idx); 35 | int cvi_get_ch_info_random(cvi_dma_ch_desc_t *ch_info); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/cvi/cvi_mailbox.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | 3 | #ifndef __CVI_MAILBOX_H__ 4 | #define __CVI_MAILBOX_H__ 5 | 6 | union cpu_mailbox_info_offset{ 7 | char mbox_info; 8 | int reserved; 9 | }; 10 | 11 | union cpu_mailbox_int_clr_offset{ 12 | char mbox_int_clr; 13 | int reserved; 14 | }; 15 | 16 | union cpu_mailbox_int_mask_offset{ 17 | char mbox_int_mask; 18 | int reserved; 19 | }; 20 | 21 | union cpu_mailbox_int_offset{ 22 | char mbox_int; 23 | int reserved; 24 | }; 25 | 26 | union cpu_mailbox_int_raw_offset{ 27 | char mbox_int_raw; 28 | int reserved; 29 | }; 30 | 31 | typedef union mailbox_set 32 | { 33 | unsigned char mbox_set; 34 | unsigned int reserved; 35 | } mailbox_set; 36 | 37 | typedef union mailbox_status 38 | { 39 | unsigned char mbox_status; 40 | unsigned int reserved; 41 | } mailbox_status; 42 | 43 | typedef union cpu_mailbox_status 44 | { 45 | unsigned char mbox_status; 46 | unsigned int reserved; 47 | } cpu_mailbox_status; 48 | 49 | /* register mapping refers to mailbox user guide*/ 50 | struct cpu_mbox_int { 51 | union cpu_mailbox_int_clr_offset cpu_mbox_int_clr; 52 | union cpu_mailbox_int_mask_offset cpu_mbox_int_mask; 53 | union cpu_mailbox_int_offset cpu_mbox_int_int; 54 | union cpu_mailbox_int_raw_offset cpu_mbox_int_raw; 55 | }; 56 | 57 | struct mailbox_set_register { 58 | union cpu_mailbox_info_offset cpu_mbox_en[4]; // 0x00, 0x04, 0x08, 0x0c 59 | struct cpu_mbox_int cpu_mbox_set[4]; // 0x10~0x1C, 0x20~0x2C, 0x30~0x3C, 0x40~0x4C 60 | int reserved[4]; // 0x50~0x5C 61 | union mailbox_set mbox_set; // 0x60 62 | union mailbox_status mbox_status; // 0x64 63 | int reserved2[2]; // 0x68~0x6C 64 | union cpu_mailbox_status cpu_mbox_status[4]; // 0x70 65 | }; 66 | 67 | struct mailbox_done_register { 68 | union cpu_mailbox_info_offset cpu_mbox_done_en[4]; 69 | struct cpu_mbox_int cpu_mbox_done[4]; 70 | }; 71 | 72 | #define MAILBOX_MAX_NUM 0x0008 73 | #define MAILBOX_DONE_OFFSET 0x0002 74 | #define MAILBOX_CONTEXT_OFFSET 0x0400 75 | 76 | #define MAILBOX_REG_BASE 0x01900000 77 | #define MAILBOX_REG_BUFF (MAILBOX_REG_BASE + 0x0400) 78 | #define SPINLOCK_REG_BASE (MAILBOX_REG_BASE + 0x00c0) 79 | 80 | #define RECEIVE_CPU 2 // c906L 81 | #define SEND_TO_CPU1 1 // c906B 82 | #define SEND_TO_CPU0 0 // ca53 83 | 84 | #endif // end of__CVI_MAILBOX_H__ 85 | 86 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/cvi/cvi_spinlock.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | 3 | #ifndef __DRV_SPINLOCK_H__ 4 | #define __DRV_SPINLOCK_H__ 5 | 6 | enum SPINLOCK_FIELD 7 | { 8 | SPIN_UART, 9 | SPIN_LINUX_RTOS = 4, // this spinlock field is used for linux & rtos 10 | SPIN_MBOX = SPIN_LINUX_RTOS, 11 | SPIN_MAX = 7, 12 | }; 13 | 14 | typedef struct hw_raw_spinlock 15 | { 16 | unsigned short locks; 17 | unsigned short hw_field; 18 | } hw_raw_spinlock_t; 19 | 20 | #define MAILBOX_LOCK_SUCCESS 1 21 | #define MAILBOX_LOCK_FAILED (-1) 22 | 23 | #define __CVI_ARCH_SPIN_LOCK_UNLOCKED \ 24 | { \ 25 | 0 \ 26 | } 27 | 28 | #define __CVI_RAW_SPIN_LOCK_INITIALIZER(spinlock_hw_field) \ 29 | { \ 30 | .locks = __CVI_ARCH_SPIN_LOCK_UNLOCKED, \ 31 | .hw_field = spinlock_hw_field, \ 32 | } 33 | 34 | #define DEFINE_CVI_SPINLOCK(x, y) hw_raw_spinlock_t x = __CVI_RAW_SPIN_LOCK_INITIALIZER(y) 35 | 36 | int _hw_raw_spin_lock_irqsave(hw_raw_spinlock_t *lock); 37 | void _hw_raw_spin_unlock_irqrestore(hw_raw_spinlock_t *lock, int flag); 38 | 39 | #define drv_spin_lock_irqsave(lock, flags) \ 40 | { \ 41 | flags = _hw_raw_spin_lock_irqsave(lock); \ 42 | } 43 | 44 | #define drv_spin_unlock_irqrestore(lock, flags) \ 45 | _hw_raw_spin_unlock_irqrestore(lock, flags) 46 | 47 | void spinlock_base(unsigned long mb_base); 48 | void cvi_spinlock_init(void); 49 | 50 | #endif // end of __DRV_SPINLOCK_H__ 51 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/hal/hal_dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef __HAL_DMA_H__ 6 | #define __HAL_DMA_H__ 7 | 8 | #include 9 | #include "dw_cvi_dma_ll.h" 10 | 11 | void hal_dma_dwc_clk_set(int enable); 12 | void hal_dma_off(dw_dma_t *dma); 13 | void hal_dma_on(dw_dma_t *dma); 14 | void hal_dma_write_cfg(dw_dma_channel_t *dwc, uint64_t cfg); 15 | void hal_dma_enable_irq(dw_dma_channel_t *dwc, uint64_t int_status_reg); 16 | void hal_dma_write_llp(dw_dma_channel_t *dwc, uint64_t llp); 17 | uint64_t hal_dma_get_ch_en_status(struct dw_dma *dma); 18 | void hal_dma_ch_on(struct dw_dma *dma, uint8_t ch_mask); 19 | void hal_dma_ch_off(struct dw_dma *dma, uint8_t ch_mask); 20 | void hal_dma_ch_pause(struct dw_dma *dma, uint8_t ch_mask); 21 | void hal_dma_ch_resume(struct dw_dma *dma, uint8_t ch_mask); 22 | uint64_t hal_dma_get_intstatus(dw_dma_t *dma); 23 | void hal_dma_clear_comm_intstatus(dw_dma_t *dma); 24 | uint64_t hal_dma_dwc_read_clear_intstatus(dw_dma_channel_t *dwc); 25 | void hal_dma_dwc_clear_intstatus(dw_dma_channel_t *dwc); 26 | void hal_dma_turn_off_chans(dw_dma_t *dma); 27 | void hal_dma_reset(dw_dma_t *dma); 28 | void hal_sdma_dma_int_mux_set_c906b(void); 29 | void hal_print_dma_reg(struct dw_dma *dw); 30 | void hal_print_ch_info(struct dw_dma *dw, int ch_id); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/hal/hal_pin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) CSItek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef __PIN_H__ 6 | #define __PIN_H__ 7 | 8 | #include "csi_common.h" 9 | 10 | #define PIN_MUX_Pos (0U) 11 | #define PIN_MUX_Msk (0x7 << PIN_MUX_Pos) 12 | 13 | #define PIN_MODE_Pos (2U) 14 | #define PIN_MODE_Msk (3U << PIN_MODE_Pos) 15 | #define PIN_MODE_NONE (0U << PIN_MODE_Pos) 16 | #define PIN_MODE_PULLUP (1U << PIN_MODE_Pos) 17 | #define PIN_MODE_PULLDOWN (2U << PIN_MODE_Pos) 18 | 19 | #define PIN_DRIVE_Pos (5U) 20 | #define PIN_DRIVE_Msk (7U << PIN_DRIVE_Pos) 21 | #define PIN_DRIVE_STRENGTH_0 (1U << PIN_DRIVE_Pos) 22 | #define PIN_DRIVE_STRENGTH_1 (2U << PIN_DRIVE_Pos) 23 | 24 | #define PIN_SPEED_Pos (11U) 25 | #define PIN_SPEED_Msk (1U << PIN_SPEED_Pos) 26 | #define PIN_SPEED_FAST (0U << PIN_SPEED_Pos) 27 | #define PIN_SPEED_SLOW (1U << PIN_SPEED_Pos) 28 | 29 | #define PIN_REG(reg_base) *((__IOM uint32_t *)(reg_base)) 30 | 31 | static inline void pin_set_mux(unsigned long reg_base, uint32_t value) 32 | { 33 | pr_debug("write reg %08p value 0x%x\n", &PIN_REG(reg_base), value); 34 | PIN_REG(reg_base) &= ~PIN_MUX_Msk; 35 | PIN_REG(reg_base) |= (PIN_MUX_Msk & value); 36 | } 37 | 38 | static inline uint32_t pin_get_mux(unsigned long reg_base) 39 | { 40 | pr_debug("read reg %08p value 0x%x\n", &PIN_REG(reg_base), PIN_REG(reg_base)); 41 | return PIN_REG(reg_base) & PIN_MUX_Msk; 42 | } 43 | 44 | static inline void pin_set_mode(unsigned long reg_base, uint32_t value) 45 | { 46 | pr_debug("write reg %08p value 0x%x\n", &PIN_REG(reg_base), value); 47 | PIN_REG(reg_base) &= ~PIN_MODE_Msk; 48 | PIN_REG(reg_base) |= (PIN_MODE_Msk & value); 49 | } 50 | 51 | static inline uint32_t pin_get_mode(unsigned long reg_base) 52 | { 53 | return (PIN_REG(reg_base) & PIN_MODE_Msk); 54 | } 55 | 56 | static inline void pin_set_speed(unsigned long reg_base, uint32_t value) 57 | { 58 | pr_debug("write reg %08p value 0x%x\n", &PIN_REG(reg_base), value); 59 | PIN_REG(reg_base) &= ~PIN_SPEED_Msk; 60 | PIN_REG(reg_base) |= (PIN_SPEED_Msk & value); 61 | } 62 | 63 | static inline uint32_t pin_get_speed(unsigned long reg_base) 64 | { 65 | return (PIN_REG(reg_base) & PIN_SPEED_Msk); 66 | } 67 | 68 | static inline void pin_set_drive(unsigned long reg_base, uint32_t value) 69 | { 70 | pr_debug("write reg %08p value 0x%x\n", &PIN_REG(reg_base), value); 71 | PIN_REG(reg_base) &= ~PIN_DRIVE_Msk; 72 | PIN_REG(reg_base) |= (PIN_DRIVE_Msk & value); 73 | } 74 | 75 | static inline uint32_t pin_get_drive(unsigned long reg_base) 76 | { 77 | return (PIN_REG(reg_base) & PIN_DRIVE_Msk); 78 | } 79 | #endif 80 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/hal/hal_sysdma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef __SYSDMA_H__ 6 | #define __SYSDMA_H__ 7 | 8 | #include 9 | 10 | typedef unsigned int uint32_t; 11 | typedef unsigned char uint8_t; 12 | 13 | #define REG_SDMA_DMA_CH_REMAP0 0x03000154U 14 | #define REG_SDMA_DMA_CH_REMAP1 0x03000158U 15 | 16 | typedef enum { 17 | CVI_I2S0_RX = 0, 18 | CVI_I2S0_TX, 19 | CVI_I2S1_RX, 20 | CVI_I2S1_TX, 21 | CVI_I2S2_RX, 22 | CVI_I2S2_TX, 23 | CVI_I2S3_RX, 24 | CVI_I2S3_TX, 25 | CVI_UART0_RX, 26 | CVI_UART0_TX, 27 | CVI_UART1_RX, 28 | CVI_UART1_TX, 29 | CVI_UART2_RX, 30 | CVI_UART2_TX, 31 | CVI_UART3_RX, 32 | CVI_UART3_TX, 33 | CVI_SPI0_RX, 34 | CVI_SPI0_TX, 35 | CVI_SPI1_RX, 36 | CVI_SPI1_TX, 37 | CVI_SPI2_RX, 38 | CVI_SPI2_TX, 39 | CVI_SPI3_RX, 40 | CVI_SPI3_TX, 41 | CVI_I2C0_RX, 42 | CVI_I2C0_TX, 43 | CVI_I2C1_RX, 44 | CVI_I2C1_TX, 45 | CVI_I2C2_RX, 46 | CVI_I2C2_TX, 47 | CVI_I2C3_RX, 48 | CVI_I2C3_TX, 49 | CVI_I2C4_RX, 50 | CVI_I2C4_TX, 51 | CVI_TDM0_RX, 52 | CVI_TDM0_TX, 53 | CVI_TDM1_RX, 54 | CVI_AUDSRC, 55 | CVI_SPI_NAND, 56 | CVI_SPI_NOR, 57 | CVI_UART4_RX, 58 | CVI_UART4_TX, 59 | CVI_SPI_NOR1, 60 | } request_index_t; 61 | 62 | struct dma_remap_item{ 63 | request_index_t hs_id; 64 | uint8_t channel_id; 65 | }; 66 | 67 | void hal_dma_hs_remap_init(void); 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/mmio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef __MMIO_H__ 8 | #define __MMIO_H__ 9 | 10 | #include 11 | 12 | #define __raw_readb(a) (*(volatile unsigned char *)(a)) 13 | #define __raw_readw(a) (*(volatile unsigned short *)(a)) 14 | #define __raw_readl(a) (*(volatile unsigned int *)(a)) 15 | #define __raw_readq(a) (*(volatile unsigned long long *)(a)) 16 | 17 | #define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v)) 18 | #define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v)) 19 | #define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v)) 20 | #define __raw_writeq(v,a) (*(volatile unsigned long long *)(a) = (v)) 21 | 22 | /* 23 | * I/O memory access primitives. Reads are ordered relative to any 24 | * following Normal memory access. Writes are ordered relative to any prior 25 | * Normal memory access. The memory barriers here are necessary as RISC-V 26 | * doesn't define any ordering between the memory space and the I/O space. 27 | */ 28 | #define __io_br() do {} while (0) 29 | #define __io_ar(v) __asm__ __volatile__ ("fence i,r" : : : "memory") 30 | #define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory") 31 | //#define __io_aw() mmiowb_set_pending() 32 | #define __io_aw() do {} while (0) 33 | 34 | #define readb(c) ({ unsigned char __v; __io_br(); __v = __raw_readb(c); __io_ar(__v); __v; }) 35 | #define readw(c) ({ unsigned short __v; __io_br(); __v = __raw_readw(c); __io_ar(__v); __v; }) 36 | #define readl(c) ({ unsigned int __v; __io_br(); __v = __raw_readl(c); __io_ar(__v); __v; }) 37 | 38 | #define writeb(v, c) ({ __io_bw(); __raw_writeb((v), (c)); __io_aw(); }) 39 | #define writew(v, c) ({ __io_bw(); __raw_writew((v), (c)); __io_aw(); }) 40 | #define writel(v, c) ({ __io_bw(); __raw_writel((v), (c)); __io_aw(); }) 41 | 42 | #define readq(c) ({ unsigned long __v; __io_br(); __v = __raw_readq(c); __io_ar(__v); __v; }) 43 | #define writeq(v, c) ({ __io_bw(); __raw_writeq((v), (c)); __io_aw(); }) 44 | 45 | #define mmio_wr32 mmio_write_32 46 | #define mmio_rd32 mmio_read_32 47 | 48 | static inline void mmio_write_8(uintptr_t addr, uint8_t value) 49 | { 50 | writeb(value, (void *) addr); 51 | } 52 | 53 | static inline uint8_t mmio_read_8(uintptr_t addr) 54 | { 55 | return readb((void *) addr); 56 | } 57 | 58 | static inline void mmio_write_16(uintptr_t addr, uint16_t value) 59 | { 60 | writew(value, (void *) addr); 61 | } 62 | 63 | static inline uint16_t mmio_read_16(uintptr_t addr) 64 | { 65 | return readw((void *) addr); 66 | } 67 | 68 | static inline void mmio_write_32(uintptr_t addr, uint32_t value) 69 | { 70 | writel(value, (void *) addr); 71 | } 72 | 73 | static inline uint32_t mmio_read_32(uintptr_t addr) 74 | { 75 | return readl((void *) addr); 76 | } 77 | 78 | static inline void mmio_write_64(uintptr_t addr, uint64_t value) 79 | { 80 | writeq(value, (void *) addr); 81 | } 82 | 83 | static inline uint64_t mmio_read_64(uintptr_t addr) 84 | { 85 | return readq((void *) addr); 86 | } 87 | 88 | static inline void mmio_clrbits_32(uintptr_t addr, uint32_t clear) 89 | { 90 | writel(readl((void *) addr) & ~clear , (void *) addr); 91 | } 92 | 93 | static inline void mmio_setbits_32(uintptr_t addr, uint32_t set) 94 | { 95 | writel(readl((void *) addr) | set , (void *) addr); 96 | } 97 | 98 | static inline void mmio_clrsetbits_32(uintptr_t addr, uint32_t clear, 99 | uint32_t set) 100 | { 101 | writel((readl((void *) addr) & ~clear) | set , (void *) addr); 102 | } 103 | 104 | /* from Linux usage */ 105 | #define ioremap(a, l) (a) 106 | 107 | #define _reg_read(addr) mmio_read_32((addr)) 108 | #define _reg_write(addr, data) mmio_write_32((addr), (data)) 109 | #define _reg_write_mask(addr, mask, data) mmio_clrsetbits_32(addr, mask, data) 110 | 111 | #define ioread8 readb 112 | #define ioread16 readw 113 | #define ioread32 readl 114 | #define ioread64 readq 115 | 116 | #define iowrite8 writeb 117 | #define iowrite16 writew 118 | #define iowrite32 writel 119 | #define iowrite64 writeq 120 | 121 | #endif /* __MMIO_H__ */ 122 | -------------------------------------------------------------------------------- /cores/sg200x/bsp/include/resource_table.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | 3 | #ifndef _RSC_TABLE_H_ 4 | #define _RSC_TABLE_H_ 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | 12 | typedef uint32_t u32; 13 | typedef uint64_t u64; 14 | typedef uint8_t u8; 15 | 16 | struct resource_table { 17 | u32 ver; 18 | u32 num; 19 | u32 reserved[2]; 20 | u32 offset[0]; 21 | } __packed; 22 | 23 | struct fw_rsc_hdr { 24 | u32 type; 25 | u8 data[0]; 26 | } __packed; 27 | 28 | struct fw_rsc_carveout { 29 | u32 da; 30 | u32 pa; 31 | u32 len; 32 | u32 flags; 33 | u32 reserved; 34 | u8 name[32]; 35 | } __packed; 36 | 37 | enum fw_resource_type { 38 | RSC_CARVEOUT = 0, 39 | RSC_DEVMEM = 1, 40 | RSC_TRACE = 2, 41 | RSC_VDEV = 3, 42 | RSC_LAST = 4, 43 | RSC_VENDOR_START = 128, 44 | RSC_VENDOR_END = 512, 45 | }; 46 | 47 | #define NO_RESOURCE_ENTRIES 1 48 | 49 | #define NUM_TABLE_ENTRIES 1 50 | 51 | struct remote_resource_table { 52 | struct resource_table resource_table; 53 | u32 offset[NO_RESOURCE_ENTRIES]; 54 | struct fw_rsc_hdr carve_out; 55 | struct fw_rsc_carveout carve_out_data; 56 | } __packed; 57 | 58 | __attribute__ ((section(".resource_table"))) 59 | struct remote_resource_table resources = { 60 | .resource_table = {1, NUM_TABLE_ENTRIES, {0}}, 61 | .offset = { offsetof(struct remote_resource_table, carve_out) }, 62 | .carve_out = {RSC_CARVEOUT}, 63 | .carve_out_data = {START_ADDR, START_ADDR, 0x200000, 0x0, 0, "text"}, 64 | }; 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif -------------------------------------------------------------------------------- /cores/sg200x/bsp/startup/tick.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #include "encoding.h" 6 | #include "csi_riscv_gcc.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C"{ 10 | #endif // __cplusplus 11 | 12 | static volatile uint32_t csi_tick = 0U; 13 | static volatile uint64_t last_time_ms = 0U; 14 | static volatile uint64_t last_time_us = 0U; 15 | static volatile uint64_t timer_init_value = 0U; 16 | 17 | /** 18 | \brief The data structure of the access Clint. 19 | */ 20 | typedef struct { 21 | __IOM uint32_t MSIP0; 22 | __IOM uint32_t MSIP1; 23 | __IOM uint32_t MSIP2; 24 | __IOM uint32_t MSIP3; 25 | uint32_t RESERVED0[(0x4004000 - 0x400000C) / 4 - 1]; 26 | __IOM uint32_t MTIMECMPL0; 27 | __IOM uint32_t MTIMECMPH0; 28 | __IOM uint32_t MTIMECMPL1; 29 | __IOM uint32_t MTIMECMPH1; 30 | __IOM uint32_t MTIMECMPL2; 31 | __IOM uint32_t MTIMECMPH2; 32 | __IOM uint32_t MTIMECMPL3; 33 | __IOM uint32_t MTIMECMPH3; 34 | uint32_t RESERVED1[(0x400C000 - 0x400401C) / 4 - 1]; 35 | __IOM uint32_t SSIP0; 36 | __IOM uint32_t SSIP1; 37 | __IOM uint32_t SSIP2; 38 | __IOM uint32_t SSIP3; 39 | uint32_t RESERVED2[(0x400D000 - 0x400C00C) / 4 - 1]; 40 | __IOM uint32_t STIMECMPL0; 41 | __IOM uint32_t STIMECMPH0; 42 | __IOM uint32_t STIMECMPL1; 43 | __IOM uint32_t STIMECMPH1; 44 | __IOM uint32_t STIMECMPL2; 45 | __IOM uint32_t STIMECMPH2; 46 | __IOM uint32_t STIMECMPL3; 47 | __IOM uint32_t STIMECMPH3; 48 | } CLINT_Type; 49 | 50 | /** 51 | \brief Get MTIME 52 | \details Returns the content of the MTIME Register. 53 | \return MTIME Register value 54 | */ 55 | __ALWAYS_STATIC_INLINE uint64_t __get_MTIME(void) 56 | { 57 | uint64_t result; 58 | 59 | __ASM volatile("rdtime %0" : "=r"(result)); 60 | //__ASM volatile("csrr %0, 0xc01" : "=r"(result)); 61 | return (result); 62 | } 63 | 64 | static inline uint32_t csi_clint_config(CLINT_Type *clint, uint32_t ticks, int32_t IRQn) 65 | { 66 | #ifdef __QEMU_RUN 67 | uint64_t value = (((uint64_t)clint->MTIMECMPH0) << 32) + (uint64_t)clint->MTIMECMPL0; 68 | 69 | value = value + (uint64_t)ticks; 70 | clint->MTIMECMPH0 = (uint32_t)(value >> 32); 71 | clint->MTIMECMPL0 = (uint32_t)value; 72 | #else 73 | uint64_t value = (((uint64_t)clint->MTIMECMPH0) << 32) + (uint64_t)clint->MTIMECMPL0; 74 | 75 | if ((value != 0) && (value != 0xffffffffffffffff)) { 76 | value = value + (uint64_t)ticks; 77 | } else { 78 | value = __get_MTIME() + ticks; 79 | } 80 | clint->MTIMECMPH0 = (uint32_t)(value >> 32); 81 | clint->MTIMECMPL0 = (uint32_t)value; 82 | #endif /*__QEMU_RUN*/ 83 | 84 | return (0UL); 85 | } 86 | 87 | void csi_tick_increase(void) 88 | { 89 | csi_tick++; 90 | } 91 | 92 | static void tick_irq_handler(int irqn, void *priv) 93 | { 94 | csi_tick_increase(); 95 | csi_clint_config((CLINT_Type *)priv, clockCyclesPerTick(), IRQ_M_TIMER); 96 | } 97 | 98 | void tick_init(void) 99 | { 100 | CLINT_Type *clint = (CLINT_Type *)CLINT_BASE; 101 | 102 | csi_tick = 0U; 103 | 104 | timer_init_value = csi_clint_get_value(); 105 | attach_irq(IRQ_M_TIMER, &tick_irq_handler, 0, "M TIMER int", clint); 106 | set_priority_irq(IRQ_M_TIMER, 31U); 107 | clint->MTIMECMPH0 = 0; 108 | clint->MTIMECMPL0 = 0; 109 | 110 | csi_clint_config(clint, clockCyclesPerTick(), IRQ_M_TIMER); 111 | 112 | set_csr(mie, MIP_MTIP); 113 | } 114 | 115 | void csi_tick_uninit(void) 116 | { 117 | disable_irq(IRQ_M_TIMER); 118 | } 119 | 120 | uint32_t csi_tick_get(void) 121 | { 122 | return csi_tick; 123 | } 124 | 125 | uint64_t millis(void) 126 | { 127 | uint64_t time; 128 | 129 | time = ((csi_clint_get_value() - timer_init_value) * 1000U / (uint64_t)F_CPU); 130 | last_time_ms = time; 131 | return time; 132 | } 133 | 134 | uint64_t micros(void) 135 | { 136 | uint64_t time; 137 | 138 | time = (csi_clint_get_value() - timer_init_value) * 1000U * 1000U / F_CPU; 139 | last_time_us = time; 140 | return time; 141 | } 142 | 143 | #ifdef __cplusplus 144 | } // extern "C" 145 | #endif 146 | -------------------------------------------------------------------------------- /cores/sg200x/include/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino.h - Main include file for the Arduino SDK 3 | Copyright (c) 2014 Arduino LLC. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Arduino_h 21 | #define Arduino_h 22 | 23 | #include "common.h" 24 | #include "stdlib_noniso.h" 25 | #include "wiring_digital.h" 26 | #include "wiring_analog.h" 27 | #include "wiring_shift.h" 28 | #include "WInterrupts.h" 29 | #include "misc.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C"{ 33 | #endif // __cplusplus 34 | 35 | void yield(void); 36 | 37 | static void __empty() { 38 | // Empty 39 | } 40 | void yield(void) __attribute__ ((weak, alias("__empty"))); 41 | 42 | #ifdef __cplusplus 43 | } // extern "C" 44 | 45 | #include "WCharacter.h" 46 | #include "WString.h" 47 | #include "WMath.h" 48 | #include "HardwareSerial.h" 49 | #include "wiring_pulse.h" 50 | #include "Tone.h" 51 | #include "ControlPWM.h" 52 | 53 | #endif // __cplusplus 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /cores/sg200x/include/ControlPWM.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONTROLPWM_H_ 2 | #define _CONTROLPWM_H_ 3 | 4 | extern void setPWM(uint8_t _pin, unsigned int _pulse, unsigned int _period); 5 | 6 | #endif /* _CONTROLPWM_H_ */ 7 | -------------------------------------------------------------------------------- /cores/sg200x/include/HardwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include "Stream.h" 23 | #include "csi_uart.h" 24 | 25 | #define SERIAL_PARITY_EVEN (UART_PARITY_EVEN << 5) 26 | #define SERIAL_PARITY_ODD (UART_PARITY_ODD << 5) 27 | #define SERIAL_PARITY_NONE (UART_PARITY_NONE << 5) 28 | #define SERIAL_PARITY(config) (csi_uart_parity_t)((config >> 5) & 0x3) 29 | 30 | #define SERIAL_STOP_BIT_1 (UART_STOP_BITS_1 << 3) 31 | #define SERIAL_STOP_BIT_1_5 (UART_STOP_BITS_1_5 << 3) 32 | #define SERIAL_STOP_BIT_2 (UART_STOP_BITS_2 << 3) 33 | #define SERIAL_STOP(config) (csi_uart_stop_bits_t)((config >> 3) & 3) 34 | 35 | #define SERIAL_DATA_5 (UART_DATA_BITS_5) 36 | #define SERIAL_DATA_6 (UART_DATA_BITS_6) 37 | #define SERIAL_DATA_7 (UART_DATA_BITS_7) 38 | #define SERIAL_DATA_8 (UART_DATA_BITS_8) 39 | #define SERIAL_DATA(config) (csi_uart_data_bits_t)(config & 0x7) 40 | 41 | #define SERIAL_5N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_5) 42 | #define SERIAL_6N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_6) 43 | #define SERIAL_7N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_7) 44 | #define SERIAL_8N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_8) 45 | #define SERIAL_5N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_5) 46 | #define SERIAL_6N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_6) 47 | #define SERIAL_7N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_7) 48 | #define SERIAL_8N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_8) 49 | #define SERIAL_5E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_5) 50 | #define SERIAL_6E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_6) 51 | #define SERIAL_7E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_7) 52 | #define SERIAL_8E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_8) 53 | #define SERIAL_5E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_5) 54 | #define SERIAL_6E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_6) 55 | #define SERIAL_7E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_7) 56 | #define SERIAL_8E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_8) 57 | #define SERIAL_5O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_5) 58 | #define SERIAL_6O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_6) 59 | #define SERIAL_7O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_7) 60 | #define SERIAL_8O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_8) 61 | #define SERIAL_5O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_5) 62 | #define SERIAL_6O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_6) 63 | #define SERIAL_7O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_7) 64 | #define SERIAL_8O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_8) 65 | 66 | class HardwareSerial : public Stream 67 | { 68 | public: 69 | HardwareSerial(int uartNum, uint8_t rxPin, uint8_t txPin); 70 | ~HardwareSerial(); 71 | 72 | void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1); 73 | void end(); 74 | 75 | int available(void); 76 | 77 | // rtt serial driver not support. 78 | int peek(void); 79 | void flush(void) {} 80 | 81 | int read(void); 82 | size_t read(uint8_t *buffer, size_t size); 83 | inline size_t read(char * buffer, size_t size) { 84 | return read((uint8_t*) buffer, size); 85 | } 86 | 87 | void setTimeout(unsigned long timeout) { _timeout = timeout; } 88 | unsigned long getTimeout(void) { return _timeout; } 89 | 90 | size_t write(uint8_t); 91 | size_t write(const uint8_t *buffer, size_t size); 92 | using Print::write; // pull in write(str) and write(buf, size) from Print 93 | int availableForWrite() { return 0; } 94 | 95 | operator bool() const; 96 | 97 | protected: 98 | int _uartNum; 99 | unsigned long _timeout; 100 | csi_uart_t _uart; 101 | uint8_t _data; 102 | bool _data_valid; 103 | 104 | uint8_t _rxPin, _txPin; 105 | }; 106 | 107 | #define Serial Serial3 108 | 109 | #if SERIAL_INTERFACES_COUNT > 0 110 | extern HardwareSerial Serial0; 111 | #endif 112 | #if SERIAL_INTERFACES_COUNT > 1 113 | extern HardwareSerial Serial1; 114 | #endif 115 | #if SERIAL_INTERFACES_COUNT > 2 116 | extern HardwareSerial Serial2; 117 | #endif 118 | #if SERIAL_INTERFACES_COUNT > 3 119 | extern HardwareSerial Serial3; 120 | #endif 121 | 122 | #if SERIAL_INTERFACES_COUNT > 4 123 | extern HardwareSerial Serial4; 124 | #endif 125 | 126 | // XXX: Are we keeping the serialEvent API? 127 | extern void serialEventRun(void) __attribute__((weak)); 128 | -------------------------------------------------------------------------------- /cores/sg200x/include/Print.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include // for size_t 23 | 24 | #include "WString.h" 25 | #include "Printable.h" 26 | 27 | #define DEC 10 28 | #define HEX 16 29 | #define OCT 8 30 | #define BIN 2 31 | 32 | class Print 33 | { 34 | private: 35 | int write_error; 36 | size_t printNumber(unsigned long, uint8_t); 37 | size_t printNumber(unsigned long long, uint8_t); 38 | size_t printFloat(double, uint8_t); 39 | protected: 40 | void setWriteError(int err = 1) { write_error = err; } 41 | public: 42 | Print() : write_error(0) {} 43 | 44 | int getWriteError() { return write_error; } 45 | void clearWriteError() { setWriteError(0); } 46 | 47 | virtual size_t write(uint8_t) = 0; 48 | size_t write(const char *str) 49 | { 50 | if (str == NULL) return 0; 51 | return write((const uint8_t *)str, strlen(str)); 52 | } 53 | 54 | virtual size_t write(const uint8_t *buffer, size_t size); 55 | size_t write(const char *buffer, size_t size) 56 | { 57 | return write((const uint8_t *)buffer, size); 58 | } 59 | 60 | size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3))); 61 | 62 | // add availableForWrite to make compatible with Arduino Print.h 63 | // default to zero, meaning "a single write may block" 64 | // should be overriden by subclasses with buffering 65 | virtual int availableForWrite() { return 0; } 66 | 67 | size_t print(const __FlashStringHelper *); 68 | size_t print(const String &); 69 | size_t print(const char[]); 70 | size_t print(char); 71 | size_t print(unsigned char, int = DEC); 72 | size_t print(int, int = DEC); 73 | size_t print(unsigned int, int = DEC); 74 | size_t print(long, int = DEC); 75 | size_t print(unsigned long, int = DEC); 76 | size_t print(long long, int = DEC); 77 | size_t print(unsigned long long, int = DEC); 78 | size_t print(double, int = 2); 79 | size_t print(const Printable&); 80 | 81 | size_t println(const __FlashStringHelper *); 82 | size_t println(const String &s); 83 | size_t println(const char[]); 84 | size_t println(char); 85 | size_t println(unsigned char, int = DEC); 86 | size_t println(int, int = DEC); 87 | size_t println(unsigned int, int = DEC); 88 | size_t println(long, int = DEC); 89 | size_t println(unsigned long, int = DEC); 90 | size_t println(long long, int = DEC); 91 | size_t println(unsigned long long, int = DEC); 92 | size_t println(double, int = 2); 93 | size_t println(const Printable&); 94 | size_t println(void); 95 | 96 | virtual void flush() { /* Empty implementation for backward compatibility */ } 97 | }; 98 | -------------------------------------------------------------------------------- /cores/sg200x/include/Printable.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | class Print; 24 | 25 | /** The Printable class provides a way for new classes to allow themselves to be printed. 26 | By deriving from Printable and implementing the printTo method, it will then be possible 27 | for users to print out instances of this class by passing them into the usual 28 | Print::print and Print::println methods. 29 | */ 30 | 31 | class Printable 32 | { 33 | public: 34 | virtual size_t printTo(Print& p) const = 0; 35 | }; 36 | -------------------------------------------------------------------------------- /cores/sg200x/include/RingBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifdef __cplusplus 20 | 21 | #ifndef _RING_BUFFER_ 22 | #define _RING_BUFFER_ 23 | 24 | #include 25 | #include 26 | 27 | // Define constants and variables for buffering incoming serial data. We're 28 | // using a ring buffer (I think), in which head is the index of the location 29 | // to which to write the next incoming character and tail is the index of the 30 | // location from which to read. 31 | #define SERIAL_BUFFER_SIZE 64 32 | 33 | template 34 | class RingBufferN 35 | { 36 | public: 37 | uint8_t _aucBuffer[N]; 38 | volatile int _iHead; 39 | volatile int _iTail; 40 | volatile int _numElems; 41 | 42 | public: 43 | RingBufferN(void); 44 | void store_char(uint8_t c); 45 | void clear(); 46 | int read_char(); 47 | int available(); 48 | int availableForStore(); 49 | int peek(); 50 | bool isFull(); 51 | 52 | private: 53 | int nextIndex(int index); 54 | inline bool isEmpty() const { return (_numElems == 0); } 55 | }; 56 | 57 | typedef RingBufferN RingBuffer; 58 | 59 | 60 | template 61 | RingBufferN::RingBufferN(void) 62 | { 63 | memset(_aucBuffer, 0, N); 64 | clear(); 65 | } 66 | 67 | template 68 | void RingBufferN::store_char(uint8_t c) 69 | { 70 | // if we should be storing the received character into the location 71 | // just before the tail (meaning that the head would advance to the 72 | // current location of the tail), we're about to overflow the buffer 73 | // and so we don't write the character or advance the head. 74 | if (!isFull()) { 75 | _aucBuffer[_iHead] = c ; 76 | _iHead = nextIndex(_iHead); 77 | _numElems++; 78 | } 79 | } 80 | 81 | template 82 | void RingBufferN::clear() 83 | { 84 | _iHead = 0; 85 | _iTail = 0; 86 | _numElems = 0; 87 | } 88 | 89 | template 90 | int RingBufferN::read_char() 91 | { 92 | if (isEmpty()) 93 | return -1; 94 | 95 | uint8_t value = _aucBuffer[_iTail]; 96 | _iTail = nextIndex(_iTail); 97 | _numElems--; 98 | 99 | return value; 100 | } 101 | 102 | template 103 | int RingBufferN::available() 104 | { 105 | return _numElems; 106 | } 107 | 108 | template 109 | int RingBufferN::availableForStore() 110 | { 111 | return (N - _numElems); 112 | } 113 | 114 | template 115 | int RingBufferN::peek() 116 | { 117 | if (isEmpty()) 118 | return -1; 119 | 120 | return _aucBuffer[_iTail]; 121 | } 122 | 123 | template 124 | int RingBufferN::nextIndex(int index) 125 | { 126 | return (uint32_t)(index + 1) % N; 127 | } 128 | 129 | template 130 | bool RingBufferN::isFull() 131 | { 132 | return (_numElems == N); 133 | } 134 | 135 | #endif /* _RING_BUFFER_ */ 136 | #endif /* __cplusplus */ 137 | -------------------------------------------------------------------------------- /cores/sg200x/include/Tone.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _TONE_H_ 20 | #define _TONE_H_ 21 | 22 | extern void tone(uint8_t _pin, unsigned int frequency); 23 | extern void tone(uint8_t _pin, unsigned int frequency, unsigned long duration); 24 | extern void noTone(uint8_t _pin); 25 | 26 | #endif /* _TONE_H_ */ 27 | -------------------------------------------------------------------------------- /cores/sg200x/include/WCharacter.h: -------------------------------------------------------------------------------- 1 | /* 2 | WCharacter.h - Character utility functions for Wiring & Arduino 3 | Copyright (c) 2010 Hernando Barragan. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Character_h 21 | #define Character_h 22 | 23 | #include 24 | #define isascii(__c) ((unsigned)(__c)<=0177) 25 | #define toascii(__c) ((__c)&0177) 26 | 27 | // WCharacter.h prototypes 28 | inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); 29 | inline boolean isAlpha(int c) __attribute__((always_inline)); 30 | inline boolean isAscii(int c) __attribute__((always_inline)); 31 | inline boolean isWhitespace(int c) __attribute__((always_inline)); 32 | inline boolean isControl(int c) __attribute__((always_inline)); 33 | inline boolean isDigit(int c) __attribute__((always_inline)); 34 | inline boolean isGraph(int c) __attribute__((always_inline)); 35 | inline boolean isLowerCase(int c) __attribute__((always_inline)); 36 | inline boolean isPrintable(int c) __attribute__((always_inline)); 37 | inline boolean isPunct(int c) __attribute__((always_inline)); 38 | inline boolean isSpace(int c) __attribute__((always_inline)); 39 | inline boolean isUpperCase(int c) __attribute__((always_inline)); 40 | inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); 41 | inline int toAscii(int c) __attribute__((always_inline)); 42 | inline int toLowerCase(int c) __attribute__((always_inline)); 43 | inline int toUpperCase(int c) __attribute__((always_inline)); 44 | 45 | // Checks for an alphanumeric character. 46 | // It is equivalent to (isalpha(c) || isdigit(c)). 47 | inline boolean isAlphaNumeric(int c) 48 | { 49 | return (isalnum(c) == 0 ? false : true); 50 | } 51 | 52 | // Checks for an alphabetic character. 53 | // It is equivalent to (isupper(c) || islower(c)). 54 | inline boolean isAlpha(int c) 55 | { 56 | return (isalpha(c) == 0 ? false : true); 57 | } 58 | 59 | // Checks whether c is a 7-bit unsigned char value 60 | // that fits into the ASCII character set. 61 | inline boolean isAscii(int c) 62 | { 63 | return (isascii (c) == 0 ? false : true); 64 | } 65 | 66 | // Checks for a blank character, that is, a space or a tab. 67 | inline boolean isWhitespace(int c) 68 | { 69 | return (isblank(c) == 0 ? false : true); 70 | } 71 | 72 | // Checks for a control character. 73 | inline boolean isControl(int c) 74 | { 75 | return (iscntrl(c) == 0 ? false : true); 76 | } 77 | 78 | // Checks for a digit (0 through 9). 79 | inline boolean isDigit(int c) 80 | { 81 | return (isdigit(c) == 0 ? false : true); 82 | } 83 | 84 | // Checks for any printable character except space. 85 | inline boolean isGraph(int c) 86 | { 87 | return (isgraph(c) == 0 ? false : true); 88 | } 89 | 90 | // Checks for a lower-case character. 91 | inline boolean isLowerCase(int c) 92 | { 93 | return (islower(c) == 0 ? false : true); 94 | } 95 | 96 | // Checks for any printable character including space. 97 | inline boolean isPrintable(int c) 98 | { 99 | return (isprint(c) == 0 ? false : true); 100 | } 101 | 102 | // Checks for any printable character which is not a space 103 | // or an alphanumeric character. 104 | inline boolean isPunct(int c) 105 | { 106 | return (ispunct(c) == 0 ? false : true); 107 | } 108 | 109 | // Checks for white-space characters. For the avr-libc library, 110 | // these are: space, formfeed ('\f'), newline ('\n'), carriage 111 | // return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). 112 | inline boolean isSpace(int c) 113 | { 114 | return (isspace(c) == 0 ? false : true); 115 | } 116 | 117 | // Checks for an uppercase letter. 118 | inline boolean isUpperCase(int c) 119 | { 120 | return (isupper(c) == 0 ? false : true); 121 | } 122 | 123 | // Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 124 | // 8 9 a b c d e f A B C D E F. 125 | inline boolean isHexadecimalDigit(int c) 126 | { 127 | return (isxdigit(c) == 0 ? false : true); 128 | } 129 | 130 | // Converts c to a 7-bit unsigned char value that fits into the 131 | // ASCII character set, by clearing the high-order bits. 132 | inline int toAscii(int c) 133 | { 134 | return toascii(c); 135 | } 136 | 137 | // Warning: 138 | // Many people will be unhappy if you use this function. 139 | // This function will convert accented letters into random 140 | // characters. 141 | 142 | // Converts the letter c to lower case, if possible. 143 | inline int toLowerCase(int c) 144 | { 145 | return tolower(c); 146 | } 147 | 148 | // Converts the letter c to upper case, if possible. 149 | inline int toUpperCase(int c) 150 | { 151 | return toupper(c); 152 | } 153 | 154 | #endif 155 | -------------------------------------------------------------------------------- /cores/sg200x/include/WInterrupts.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011-2012 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_INTERRUPTS_ 20 | #define _WIRING_INTERRUPTS_ 21 | 22 | #include "common.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | void attachInterrupt(pin_size_t pin, void (*callback)(void), uint32_t mode); 29 | 30 | void detachInterrupt(pin_size_t pin); 31 | 32 | #define interrupts() { \ 33 | __ASM volatile("csrs mstatus, 8"); \ 34 | __ASM volatile("li a0, 0x888"); \ 35 | __ASM volatile("csrs mie, a0"); \ 36 | } 37 | #define noInterrupts() { \ 38 | __ASM volatile("csrc mstatus, 8"); \ 39 | } 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif /* _WIRING_INTERRUPTS_ */ 46 | -------------------------------------------------------------------------------- /cores/sg200x/include/WMath.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_MATH_ 20 | #define _WIRING_MATH_ 21 | 22 | long random(long) ; 23 | long random(long, long) ; 24 | void randomSeed(uint32_t dwSeed) ; 25 | long map(long, long, long, long, long) ; 26 | 27 | uint16_t makeWord(uint16_t w) ; 28 | uint16_t makeWord(uint8_t h, uint8_t l) ; 29 | 30 | #define word(...) makeWord(__VA_ARGS__) 31 | 32 | #endif /* _WIRING_MATH_ */ 33 | -------------------------------------------------------------------------------- /cores/sg200x/include/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #ifndef COMMON_H 22 | #define COMMON_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "variant.h" 34 | 35 | #include "binary.h" 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | #define __WEAK __attribute__((weak)) 42 | 43 | #ifndef __ALWAYS_STATIC_INLINE 44 | #define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline 45 | #endif 46 | 47 | #ifndef __ASM 48 | #define __ASM __asm /*!< asm keyword for GNU Compiler */ 49 | #endif 50 | 51 | #ifndef __STATIC_INLINE 52 | #define __STATIC_INLINE static inline 53 | #endif 54 | 55 | #define __IM volatile const /*! Defines 'read only' structure member permissions */ 56 | #define __OM volatile /*! Defines 'write only' structure member permissions */ 57 | #define __IOM volatile /*! Defines 'read / write' structure member permissions */ 58 | 59 | typedef enum { 60 | LOW = 0, 61 | HIGH = 1, 62 | CHANGE = 2, 63 | FALLING = 3, 64 | RISING = 4, 65 | } PinStatus; 66 | 67 | typedef enum { 68 | INPUT = 0x0, 69 | OUTPUT = 0x1, 70 | INPUT_PULLUP = 0x2, 71 | INPUT_PULLDOWN = 0x3, 72 | OUTPUT_OPENDRAIN = 0x4, 73 | } PinMode; 74 | 75 | #define PI 3.1415926535897932384626433832795 76 | #define HALF_PI 1.5707963267948966192313216916398 77 | #define TWO_PI 6.283185307179586476925286766559 78 | #define DEG_TO_RAD 0.017453292519943295769236907684886 79 | #define RAD_TO_DEG 57.295779513082320876798154814105 80 | #define EULER 2.718281828459045235360287471352 81 | 82 | #define min(a, b) ((a) < (b) ? (a) : (b)) 83 | #define max(a, b) ((a) > (b) ? (a) : (b)) 84 | #define abs(x) ((x) > 0 ? (x) : -(x)) // abs() comes from STL 85 | #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) 86 | #define round(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5)) // round() comes from STL 87 | #define radians(deg) ((deg) * DEG_TO_RAD) 88 | #define degrees(rad) ((rad) * RAD_TO_DEG) 89 | #define sq(x) ((x) * (x)) 90 | #define clockCyclesPerTick() (F_CPU / 100L) 91 | #define clockCyclesPerMicrosecond() (F_CPU / 1000000L) 92 | #define clockCyclesToMicroseconds(a) (((a) * 1000L) / (F_CPU / 1000L)) 93 | #define microsecondsToClockCycles(a) ((a) * (F_CPU / 1000000L)) 94 | 95 | #define lowByte(w) ((uint8_t)((w) & 0xff)) 96 | #define highByte(w) ((uint8_t)((w) >> 8)) 97 | 98 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 99 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 100 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 101 | #define bitToggle(value, bit) ((value) ^= (1UL << (bit))) 102 | #define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit)) 103 | 104 | #define bit(b) (1UL << (b)) 105 | 106 | typedef bool boolean; 107 | typedef uint8_t byte; 108 | typedef unsigned int word; 109 | typedef uint8_t pin_size_t; 110 | 111 | typedef int (*irq_handler_t)(int irqn, void *priv); 112 | void init(void); 113 | void irq_init(void); 114 | void tick_init(void); 115 | void disable_irq(unsigned int irqn); 116 | void enable_irq(unsigned int irqn); 117 | int attach_irq(int irqn, irq_handler_t handler, unsigned long flags, 118 | const char *name, void *priv); 119 | int request_irq(int irqn, irq_handler_t handler, unsigned long flags, 120 | const char *name, void *priv); 121 | int detach_irq(int irqn); 122 | void set_priority_irq(int irq_num, int priority); 123 | 124 | #ifdef __cplusplus 125 | } 126 | 127 | void setup(void); 128 | void loop(void); 129 | 130 | #endif 131 | #endif 132 | -------------------------------------------------------------------------------- /cores/sg200x/include/mailbox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef _MAILBOX_H_ 6 | #define _MAILBOX_H_ 7 | 8 | #include "common.h" 9 | 10 | #define NUM_MAILBOX_CHANNELS 8 11 | 12 | class MailboxMsg { 13 | public: 14 | uint32_t *data; 15 | int channel = 0; 16 | }; 17 | 18 | void mailbox_init (bool master); 19 | void mailbox_register (int channel, void(*callback)(MailboxMsg)); 20 | void mailbox_unregister (int channel); 21 | void mailbox_enable_receive (int channel); 22 | void mailbox_disable_receive (int channel); 23 | void mailbox_write(MailboxMsg& msg); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /cores/sg200x/include/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #ifndef _WIRING_ 6 | #define _WIRING_ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include 13 | #include "wiring_constants.h" 14 | 15 | unsigned long millis(void); 16 | unsigned long micros(void); 17 | void delay(unsigned long); 18 | void delayMicroseconds(unsigned long us); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* _WIRING_ */ 25 | -------------------------------------------------------------------------------- /cores/sg200x/include/pgmspace.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 3 | This file is part of the RaspberryPi core for Arduino environment. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef PGMSPACE_INCLUDE 20 | #define PGMSPACE_INCLUDE 21 | 22 | typedef void prog_void; 23 | typedef char prog_char; 24 | typedef unsigned char prog_uchar; 25 | typedef char prog_int8_t; 26 | typedef unsigned char prog_uint8_t; 27 | typedef short prog_int16_t; 28 | typedef unsigned short prog_uint16_t; 29 | typedef long prog_int32_t; 30 | typedef unsigned long prog_uint32_t; 31 | 32 | #define PROGMEM 33 | #define PGM_P const char * 34 | #define PGM_VOID_P const void * 35 | #define PSTR(s) (s) 36 | #define _SFR_BYTE(n) (n) 37 | 38 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 39 | #define pgm_read_word(addr) ({ \ 40 | typeof(addr) _addr = (addr); \ 41 | *(const unsigned short *)(_addr); \ 42 | }) 43 | #define pgm_read_dword(addr) ({ \ 44 | typeof(addr) _addr = (addr); \ 45 | *(const unsigned long *)(_addr); \ 46 | }) 47 | #define pgm_read_float(addr) ({ \ 48 | typeof(addr) _addr = (addr); \ 49 | *(const float *)(_addr); \ 50 | }) 51 | #define pgm_read_ptr(addr) ({ \ 52 | typeof(addr) _addr = (addr); \ 53 | *(void * const *)(_addr); \ 54 | }) 55 | 56 | #define pgm_get_far_address(x) ((uint32_t)(&(x))) 57 | 58 | #define pgm_read_byte_near(addr) pgm_read_byte(addr) 59 | #define pgm_read_word_near(addr) pgm_read_word(addr) 60 | #define pgm_read_dword_near(addr) pgm_read_dword(addr) 61 | #define pgm_read_float_near(addr) pgm_read_float(addr) 62 | #define pgm_read_ptr_near(addr) pgm_read_ptr(addr) 63 | #define pgm_read_byte_far(addr) pgm_read_byte(addr) 64 | #define pgm_read_word_far(addr) pgm_read_word(addr) 65 | #define pgm_read_dword_far(addr) pgm_read_dword(addr) 66 | #define pgm_read_float_far(addr) pgm_read_float(addr) 67 | #define pgm_read_ptr_far(addr) pgm_read_ptr(addr) 68 | 69 | #define memcmp_P memcmp 70 | #define memccpy_P memccpy 71 | #define memmem_P memmem 72 | #define memcpy_P memcpy 73 | #define strcpy_P strcpy 74 | #define strncpy_P strncpy 75 | #define strcat_P strcat 76 | #define strncat_P strncat 77 | #define strcmp_P strcmp 78 | #define strncmp_P strncmp 79 | #define strcasecmp_P strcasecmp 80 | #define strncasecmp_P strncasecmp 81 | #define strlen_P strlen 82 | #define strnlen_P strnlen 83 | #define strstr_P strstr 84 | #define printf_P printf 85 | #define sprintf_P sprintf 86 | #define snprintf_P snprintf 87 | #define vsnprintf_P vsnprintf 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /cores/sg200x/include/stdlib_noniso.h: -------------------------------------------------------------------------------- 1 | /* 2 | stdlib_noniso.h - nonstandard (but usefull) conversion functions 3 | 4 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef STDLIB_NONISO_H 22 | #define STDLIB_NONISO_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | int atoi(const char *s); 29 | 30 | long atol(const char* s); 31 | 32 | double atof(const char* s); 33 | 34 | char* itoa (int val, char *s, int radix); 35 | 36 | char* ltoa (long val, char *s, int radix); 37 | 38 | char* lltoa (long long val, char* s, int radix); 39 | 40 | char* utoa (unsigned int val, char *s, int radix); 41 | 42 | char* ultoa (unsigned long val, char *s, int radix); 43 | 44 | char* ulltoa (unsigned long long val, char* s, int radix); 45 | 46 | char* dtostrf (double val, signed int width, unsigned int prec, char *s); 47 | 48 | #ifdef __cplusplus 49 | } // extern "C" 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /cores/sg200x/include/wiring_analog.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_ANALOG_ 20 | #define _WIRING_ANALOG_ 21 | 22 | #include "wiring_constants.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | extern void analogReference(uint8_t mode) ; 29 | 30 | extern void analogWrite(uint8_t pin, uint32_t val) ; 31 | 32 | extern uint32_t analogRead(uint32_t ulPin) ; 33 | 34 | extern void analogReadResolution(int res); 35 | 36 | extern void analogWriteResolution(int res); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* _WIRING_ANALOG_ */ 43 | -------------------------------------------------------------------------------- /cores/sg200x/include/wiring_constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_CONSTANTS_ 20 | #define _WIRING_CONSTANTS_ 21 | 22 | #include "common.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif // __cplusplus 27 | 28 | #define HIGH 0x1 29 | #define LOW 0x0 30 | 31 | #define INPUT 0x0 32 | #define OUTPUT 0x1 33 | #define INPUT_PULLUP 0x2 34 | 35 | #ifndef true 36 | #define true 0x1 37 | #endif 38 | #ifndef false 39 | #define false 0x0 40 | #endif 41 | 42 | #define PI 3.1415926535897932384626433832795 43 | #define HALF_PI 1.5707963267948966192313216916398 44 | #define TWO_PI 6.283185307179586476925286766559 45 | #define DEG_TO_RAD 0.017453292519943295769236907684886 46 | #define RAD_TO_DEG 57.295779513082320876798154814105 47 | #define EULER 2.718281828459045235360287471352 48 | 49 | #define SERIAL 0x0 50 | #define DISPLAY 0x1 51 | 52 | typedef enum { 53 | LSBFIRST = 0, 54 | MSBFIRST = 1 55 | } BitOrder; 56 | 57 | #define CHANGE 2 58 | #define FALLING 3 59 | #define RISING 4 60 | 61 | #define DEFAULT 1 62 | #define EXTERNAL 0 63 | 64 | // undefine stdlib's abs if encountered 65 | #ifdef abs 66 | #undef abs 67 | #endif // abs 68 | 69 | #ifndef min 70 | #define min(a,b) ((a) < (b) ? (a) : (b)) 71 | #endif // min 72 | 73 | #ifndef max 74 | #define max(a,b) ((a) > (b) ? (a) : (b)) 75 | #endif // max 76 | 77 | #define abs(x) ((x) > 0 ? (x) : -(x)) 78 | #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) 79 | #define round(x) ((x ) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5)) 80 | #define radians(deg) ((deg) * DEG_TO_RAD) 81 | #define degrees(rad) ((rad) * RAD_TO_DEG) 82 | #define sq(x) ((x) * (x)) 83 | 84 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 85 | #define highByte(w) ((uint8_t) ((w) >> 8)) 86 | 87 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 88 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 89 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 90 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 91 | 92 | typedef unsigned int word; 93 | 94 | #define bit(b) (1UL << (b)) 95 | 96 | typedef bool boolean ; 97 | typedef uint8_t byte ; 98 | 99 | #ifdef __cplusplus 100 | } // extern "C" 101 | #endif // __cplusplus 102 | 103 | #endif /* _WIRING_CONSTANTS_ */ 104 | -------------------------------------------------------------------------------- /cores/sg200x/include/wiring_digital.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_DIGITAL_ 20 | #define _WIRING_DIGITAL_ 21 | 22 | #include "wiring_constants.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | extern void pinMode(uint8_t pin, uint8_t mode) ; 29 | 30 | extern void digitalWrite(uint8_t pin, uint8_t val) ; 31 | 32 | extern int digitalRead(uint8_t pin) ; 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* _WIRING_DIGITAL_ */ 39 | -------------------------------------------------------------------------------- /cores/sg200x/include/wiring_pulse.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_PULSE_ 20 | #define _WIRING_PULSE_ 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | #include 26 | #include "wiring_constants.h" 27 | 28 | extern unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); 29 | 30 | extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = ULONG_MAX); 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif /* _WIRING_PULSE_ */ 37 | -------------------------------------------------------------------------------- /cores/sg200x/include/wiring_shift.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _WIRING_SHIFT_ 20 | #define _WIRING_SHIFT_ 21 | #include "common.h" 22 | #include "wiring_constants.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* 29 | * \brief 30 | */ 31 | extern uint8_t shiftIn(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder); 32 | 33 | /* 34 | * \brief 35 | */ 36 | extern void shiftOut(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder, uint8_t ulVal); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* _WIRING_SHIFT_ */ 43 | -------------------------------------------------------------------------------- /cores/sg200x/interrupts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "WInterrupts.h" 6 | #include "csi_gpio_pin.h" 7 | #include "csi_pin.h" 8 | 9 | extern csi_gpio_pin_t pin[]; 10 | extern pin_name_t out_pin_map[]; 11 | 12 | void attachInterrupt(pin_size_t pinNumber, void (*callback)(void), uint32_t mode) 13 | { 14 | if (OUT_PIN_NUM <= pinNumber) { 15 | return; 16 | } 17 | 18 | pin_name_t name = out_pin_map[pinNumber]; 19 | 20 | if (csi_pin_get_mux(name) != PIN_FUNC_GPIO) { 21 | pr_err("pin GPIO %d is not used as GPIO func\n", pinNumber); 22 | return; 23 | } 24 | 25 | if (pin[pinNumber].gpio == NULL) { 26 | return; 27 | } 28 | 29 | csi_gpio_irq_mode_t edge = GPIO_IRQ_MODE_RISING_EDGE; 30 | 31 | switch (mode) { 32 | case LOW: 33 | edge = GPIO_IRQ_MODE_LOW_LEVEL; 34 | break; 35 | case HIGH: 36 | edge = GPIO_IRQ_MODE_HIGH_LEVEL; 37 | break; 38 | case CHANGE: 39 | edge = GPIO_IRQ_MODE_BOTH_EDGE; 40 | break; 41 | case FALLING: 42 | edge = GPIO_IRQ_MODE_FALLING_EDGE; 43 | break; 44 | case RISING: 45 | edge = GPIO_IRQ_MODE_RISING_EDGE; 46 | break; 47 | default: 48 | edge = GPIO_IRQ_MODE_RISING_EDGE; 49 | break; 50 | } 51 | csi_gpio_pin_irq_mode(&pin[pinNumber], edge); 52 | csi_gpio_pin_attach_callback(&pin[pinNumber], callback, NULL); 53 | csi_gpio_pin_irq_enable(&pin[pinNumber], true); 54 | } 55 | 56 | void detachInterrupt(pin_size_t pinNumber) 57 | { 58 | if (OUT_PIN_NUM <= pinNumber) { 59 | return; 60 | } 61 | 62 | pin_name_t name = out_pin_map[pinNumber]; 63 | 64 | if (csi_pin_get_mux(name) != PIN_FUNC_GPIO) { 65 | pr_err("pin GPIO %d is not used as GPIO func\n", pinNumber); 66 | return; 67 | } 68 | 69 | if (pin[pinNumber].gpio == NULL) { 70 | return; 71 | } 72 | 73 | csi_gpio_pin_irq_enable(&pin[pinNumber], false); 74 | 75 | pin[pinNumber].callback = NULL; 76 | pin[pinNumber].arg = NULL; 77 | } 78 | -------------------------------------------------------------------------------- /cores/sg200x/stdlib_noniso.c: -------------------------------------------------------------------------------- 1 | /* 2 | core_esp8266_noniso.c - nonstandard (but usefull) conversion functions 3 | 4 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | Modified 03 April 2015 by Markus Sattler 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "stdlib_noniso.h" 31 | 32 | static void reverse(char* begin, char* end) 33 | { 34 | char *is = begin; 35 | char *ie = end - 1; 36 | while (is < ie) { 37 | char tmp = *ie; 38 | *ie = *is; 39 | *is = tmp; 40 | ++is; 41 | --ie; 42 | } 43 | } 44 | 45 | char* ltoa(long value, char* result, int base) 46 | { 47 | if (base < 2 || base > 16) { 48 | *result = 0; 49 | return result; 50 | } 51 | 52 | char* out = result; 53 | long quotient = abs(value); 54 | 55 | do { 56 | const long tmp = quotient / base; 57 | *out = "0123456789abcdef"[quotient - (tmp * base)]; 58 | ++out; 59 | quotient = tmp; 60 | } while (quotient); 61 | 62 | // Apply negative sign 63 | if (value < 0) 64 | *out++ = '-'; 65 | 66 | reverse(result, out); 67 | *out = 0; 68 | return result; 69 | } 70 | 71 | char* lltoa (long long val, char* result, int base) 72 | { 73 | if (base < 2 || base > 16) { 74 | *result = 0; 75 | return result; 76 | } 77 | 78 | char* out = result; 79 | long long quotient = val > 0 ? val : -val; 80 | 81 | do { 82 | const long long tmp = quotient / base; 83 | *out = "0123456789abcdef"[quotient - (tmp * base)]; 84 | ++out; 85 | quotient = tmp; 86 | } while (quotient); 87 | 88 | // Apply negative sign 89 | if (val < 0) 90 | *out++ = '-'; 91 | 92 | reverse(result, out); 93 | *out = 0; 94 | return result; 95 | } 96 | 97 | char* ultoa(unsigned long value, char* result, int base) 98 | { 99 | if (base < 2 || base > 16) { 100 | *result = 0; 101 | return result; 102 | } 103 | 104 | char* out = result; 105 | unsigned long quotient = value; 106 | 107 | do { 108 | const unsigned long tmp = quotient / base; 109 | *out = "0123456789abcdef"[quotient - (tmp * base)]; 110 | ++out; 111 | quotient = tmp; 112 | } while (quotient); 113 | 114 | reverse(result, out); 115 | *out = 0; 116 | return result; 117 | } 118 | 119 | char* ulltoa (unsigned long long val, char* result, int base) 120 | { 121 | if (base < 2 || base > 16) { 122 | *result = 0; 123 | return result; 124 | } 125 | 126 | char* out = result; 127 | unsigned long long quotient = val; 128 | 129 | do { 130 | const unsigned long long tmp = quotient / base; 131 | *out = "0123456789abcdef"[quotient - (tmp * base)]; 132 | ++out; 133 | quotient = tmp; 134 | } while (quotient); 135 | 136 | reverse(result, out); 137 | *out = 0; 138 | return result; 139 | } 140 | 141 | char * dtostrf(double number, signed int width, unsigned int prec, char *s) 142 | { 143 | bool negative = false; 144 | 145 | if (isnan(number)) { 146 | strcpy(s, "nan"); 147 | return s; 148 | } 149 | if (isinf(number)) { 150 | strcpy(s, "inf"); 151 | return s; 152 | } 153 | 154 | char* out = s; 155 | 156 | int fillme = width; // how many cells to fill for the integer part 157 | if (prec > 0) { 158 | fillme -= (prec+1); 159 | } 160 | 161 | // Handle negative numbers 162 | if (number < 0.0) { 163 | negative = true; 164 | fillme--; 165 | number = -number; 166 | } 167 | 168 | // Round correctly so that print(1.999, 2) prints as "2.00" 169 | // I optimized out most of the divisions 170 | double rounding = 2.0; 171 | for (unsigned int i = 0; i < prec; ++i) 172 | rounding *= 10.0; 173 | rounding = 1.0 / rounding; 174 | 175 | number += rounding; 176 | 177 | // Figure out how big our number really is 178 | double tenpow = 1.0; 179 | unsigned int digitcount = 1; 180 | while (number >= 10.0 * tenpow) { 181 | tenpow *= 10.0; 182 | digitcount++; 183 | } 184 | 185 | number /= tenpow; 186 | fillme -= digitcount; 187 | 188 | // Pad unused cells with spaces 189 | while (fillme-- > 0) { 190 | *out++ = ' '; 191 | } 192 | 193 | // Handle negative sign 194 | if (negative) *out++ = '-'; 195 | 196 | // Print the digits, and if necessary, the decimal point 197 | digitcount += prec; 198 | int8_t digit = 0; 199 | while (digitcount-- > 0) { 200 | digit = (int8_t)number; 201 | if (digit > 9) digit = 9; // insurance 202 | *out++ = (char)('0' | digit); 203 | if ((digitcount == prec) && (prec > 0)) { 204 | *out++ = '.'; 205 | } 206 | number -= digit; 207 | number *= 10.0; 208 | } 209 | 210 | // make sure the string is terminated 211 | *out = 0; 212 | return s; 213 | } 214 | -------------------------------------------------------------------------------- /cores/sg200x/time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 | */ 4 | 5 | #include "csi_riscv_gcc.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C"{ 9 | #endif // __cplusplus 10 | 11 | static void _500usdelay(void) 12 | { 13 | uint64_t start = csi_clint_get_value(); 14 | uint64_t cur; 15 | uint32_t cnt = (F_CPU / 1000U / 2U); 16 | 17 | while (1) { 18 | cur = csi_clint_get_value(); 19 | 20 | if (start > cur) { 21 | if ((start - cur) >= cnt) { 22 | break; 23 | } 24 | } else { 25 | if (cur - start >= cnt) { 26 | break; 27 | } 28 | } 29 | } 30 | } 31 | 32 | __WEAK void delay(uint64_t ms) 33 | { 34 | while (ms) { 35 | ms--; 36 | _500usdelay(); 37 | _500usdelay(); 38 | } 39 | } 40 | 41 | static void _10udelay(void) 42 | { 43 | uint64_t start = csi_clint_get_value(); 44 | uint32_t cnt = (F_CPU / 1000U / 100U); 45 | 46 | while (1) { 47 | uint64_t cur = csi_clint_get_value(); 48 | 49 | if (start > cur) { 50 | if ((start - cur) >= cnt) { 51 | break; 52 | } 53 | } else { 54 | if (cur - start >= cnt) { 55 | break; 56 | } 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * Ps: At least delay over 10us 63 | */ 64 | void delayMicroseconds(uint64_t us) 65 | { 66 | uint64_t ms = us / 1000; 67 | delay(ms); 68 | us -= ms * 1000; 69 | us /= 10U; 70 | while (us) { 71 | us--; 72 | _10udelay(); 73 | } 74 | } 75 | 76 | #ifdef __cplusplus 77 | } // extern "C" 78 | #endif 79 | -------------------------------------------------------------------------------- /cores/sg200x/wiring_analog.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Intel Corporation. All right reserved. 3 | Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | */ 20 | 21 | #include "common.h" 22 | #include "csi_gpio_pin.h" 23 | #include "csi_pin.h" 24 | #include "csi_adc.h" 25 | #include "csi_pwm.h" 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | extern dev_pin_map_t adc_map[]; 31 | extern dev_pin_map_t pwm_map[]; 32 | extern pin_name_t out_pin_map[]; 33 | 34 | /* Standard Arduino PWM resolution */ 35 | static int _readResolution = 10; 36 | static int _ADCResolution = 12; 37 | static int _writeResolution = 8; 38 | 39 | extern csi_gpio_pin_t pin[]; 40 | 41 | static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) 42 | { 43 | if (from == to) { 44 | return value; 45 | } 46 | if (from > to) { 47 | return value >> (from-to); 48 | } 49 | return value << (to-from); 50 | } 51 | 52 | void analogWriteResolution(int bits) 53 | { 54 | _writeResolution = bits; 55 | } 56 | 57 | void analogReadResolution(int bits) 58 | { 59 | _readResolution = bits; 60 | } 61 | 62 | void analogWrite(uint8_t pinNumber, uint32_t val) 63 | { 64 | csi_pwm_t pwm; 65 | 66 | const dev_pin_map_t* pwm_pin = target_pin_number_to_dev(pinNumber, pwm_map, 0xFF); 67 | 68 | if (pwm_pin == NULL) { 69 | pr_err("pin GPIO %d is not used as PWM func\n", pinNumber); 70 | return; 71 | } 72 | 73 | uint8_t pwm_idx = pwm_pin->idx >> 2; 74 | uint8_t pwm_channel = pwm_pin->idx & 0x3; 75 | 76 | if (csi_pin_set_mux(pwm_pin->name, pwm_pin->func)) { 77 | pr_err("pin GPIO %d fails to config as PWM func\n", pinNumber); 78 | return; 79 | }; 80 | 81 | csi_error_t ret_status = csi_pwm_init(&pwm, pwm_idx); 82 | if (ret_status != CSI_OK) { 83 | pr_err("GPIO pin %d init failed\n", pinNumber); 84 | return; 85 | } 86 | 87 | csi_pwm_out_stop(&pwm, pwm_channel); 88 | 89 | csi_pwm_out_config_continuous(&pwm, pwm_channel, 1 << _writeResolution, 90 | val & ((1 << _writeResolution) - 1), 91 | PWM_POLARITY_HIGH); 92 | csi_pwm_out_start(&pwm, pwm_channel); 93 | } 94 | 95 | uint32_t analogRead(uint32_t pinNumber) 96 | { 97 | const dev_pin_map_t* adc_pin = target_pin_number_to_dev(pinNumber, adc_map, 0xFF); 98 | 99 | if (adc_pin == NULL) { 100 | pr_err("pin GPIO %d is not used as ADC func\n", pinNumber); 101 | return; 102 | } 103 | 104 | if (csi_pin_set_mux(adc_pin->name, adc_pin->func)) { 105 | pr_err("pin GPIO %d fails to config as ADC func\n", pinNumber); 106 | return; 107 | }; 108 | 109 | pinMode(pinNumber, INPUT); 110 | 111 | csi_adc_t adc; 112 | csi_adc_init(&adc, 0); 113 | 114 | csi_adc_channel_enable(&adc, 1, true); 115 | 116 | csi_adc_start(&adc); 117 | 118 | int value = csi_adc_read(&adc); 119 | 120 | if (value < 0) { 121 | value = value & 0xFFF; 122 | } 123 | 124 | csi_adc_uninit(&adc); 125 | 126 | return mapResolution(value, _ADCResolution, _readResolution); 127 | } 128 | 129 | void analogReference(uint8_t mode) 130 | { 131 | (void)mode; 132 | return; 133 | } 134 | 135 | #ifdef __cplusplus 136 | } 137 | #endif 138 | -------------------------------------------------------------------------------- /cores/sg200x/wiring_digital.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. 3 | */ 4 | 5 | #include "wiring_digital.h" 6 | #include "csi_gpio_pin.h" 7 | #include "csi_pin.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | extern pin_name_t out_pin_map[]; 14 | extern pin_func_t out_pin_func_map[]; 15 | csi_gpio_pin_t pin[OUT_PIN_NUM]; 16 | 17 | void pinMode(uint8_t pinNumber, uint8_t pinMode) 18 | { 19 | if (OUT_PIN_NUM <= pinNumber) { 20 | return; 21 | } 22 | 23 | pin_name_t name = out_pin_map[pinNumber]; 24 | 25 | if (name == 0xFF) { 26 | pr_err("pin %d cannot be used as general GPIO\n", pinNumber); 27 | return; 28 | } 29 | 30 | if (csi_pin_get_mux(name) != out_pin_func_map[pinNumber]) { 31 | if (csi_pin_set_mux(name, out_pin_func_map[pinNumber])) { 32 | pr_err("pin %d cannot be configed as general GPIO\n", pinNumber); 33 | return; 34 | } 35 | } 36 | 37 | if (pin[pinNumber].gpio == NULL) { 38 | csi_error_t ret_status = csi_gpio_pin_init(&pin[pinNumber], name); 39 | if (ret_status != CSI_OK) { 40 | pr_err("GPIO pin %d init failed\n", pinNumber); 41 | return; 42 | } 43 | } 44 | 45 | csi_gpio_mode_t mode = GPIO_MODE_PULLNONE; 46 | csi_gpio_dir_t dir = GPIO_DIRECTION_INPUT; 47 | 48 | switch (pinMode) { 49 | case INPUT: 50 | break; 51 | case INPUT_PULLUP: 52 | mode = GPIO_MODE_PULLUP; 53 | break; 54 | case INPUT_PULLDOWN: 55 | mode = GPIO_MODE_PULLDOWN; 56 | break; 57 | case OUTPUT: 58 | dir = GPIO_DIRECTION_OUTPUT; 59 | break; 60 | case OUTPUT_OPENDRAIN: 61 | dir = GPIO_DIRECTION_OUTPUT; 62 | mode = GPIO_MODE_OPEN_DRAIN; 63 | break; 64 | default: 65 | break; 66 | } 67 | 68 | csi_gpio_pin_dir(&pin[pinNumber], dir); 69 | csi_pin_mode(name, mode); 70 | } 71 | 72 | void digitalWrite(uint8_t pinNumber, uint8_t status) 73 | { 74 | if (OUT_PIN_NUM <= pinNumber) { 75 | return; 76 | } 77 | 78 | pin_name_t name = out_pin_map[pinNumber]; 79 | 80 | if (csi_pin_get_mux(name) != out_pin_func_map[pinNumber]) { 81 | pr_err("pin GPIO %d is not used as GPIO func\n", pinNumber); 82 | return; 83 | } 84 | 85 | if (pin[pinNumber].gpio == NULL) { 86 | return; 87 | } 88 | 89 | csi_gpio_pin_write(&pin[pinNumber], (LOW == status) ? GPIO_PIN_LOW : GPIO_PIN_HIGH); 90 | 91 | } 92 | 93 | int digitalRead(uint8_t pinNumber) 94 | { 95 | if (OUT_PIN_NUM <= pinNumber) { 96 | return; 97 | } 98 | 99 | pin_name_t name = out_pin_map[pinNumber]; 100 | 101 | if (csi_pin_get_mux(name) != out_pin_func_map[pinNumber]) { 102 | pr_err("pin GPIO %d is not used as GPIO func\n", pinNumber); 103 | return; 104 | } 105 | 106 | if (pin[pinNumber].gpio == NULL) { 107 | return; 108 | } 109 | 110 | return csi_gpio_pin_read(&pin[pinNumber]) == GPIO_PIN_LOW ? LOW : HIGH; 111 | } 112 | 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | -------------------------------------------------------------------------------- /cores/sg200x/wiring_pulse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | pulse.c - wiring pulseIn implementation for esp8266 3 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 4 | This file is part of the esp8266 core for Arduino environment. 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | You should have received a copy of the GNU Lesser General Public 14 | License along with this library; if not, write to the Free Software 15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 | */ 17 | 18 | #include "Arduino.h" 19 | #include "wiring_pulse.h" 20 | #include "common.h" 21 | #include "csi_riscv_gcc.h" 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define WAIT_FOR_PIN_STATE(state) \ 29 | while (digitalRead(pin) != (state)) { \ 30 | if (csi_clint_get_value() - start_cycle_count > timeout_cycles) { \ 31 | return 0; \ 32 | } \ 33 | } 34 | 35 | // max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock 36 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) 37 | { 38 | const uint32_t max_timeout_us = clockCyclesToMicroseconds(ULONG_MAX); 39 | if (timeout > max_timeout_us) { 40 | timeout = max_timeout_us; 41 | } 42 | const uint64_t timeout_cycles = microsecondsToClockCycles(timeout); 43 | const uint64_t start_cycle_count = csi_clint_get_value(); 44 | WAIT_FOR_PIN_STATE(!state); 45 | WAIT_FOR_PIN_STATE(state); 46 | const uint64_t pulse_start_cycle_count = csi_clint_get_value(); 47 | WAIT_FOR_PIN_STATE(!state); 48 | uint64_t result = csi_clint_get_value() - pulse_start_cycle_count; 49 | return clockCyclesToMicroseconds(result); 50 | } 51 | 52 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) 53 | { 54 | return pulseIn(pin, state, timeout); 55 | } 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /cores/sg200x/wiring_shift.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | #include "wiring_constants.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C"{ 24 | #endif 25 | 26 | uint8_t shiftIn(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder) 27 | { 28 | uint8_t value = 0 ; 29 | uint8_t i ; 30 | 31 | for (i = 0 ; i < 8 ; ++i) { 32 | digitalWrite(ulClockPin, HIGH) ; 33 | 34 | if (ulBitOrder == LSBFIRST) { 35 | value |= digitalRead(ulDataPin) << i ; 36 | } else { 37 | value |= digitalRead(ulDataPin) << (7 - i) ; 38 | } 39 | 40 | digitalWrite(ulClockPin, LOW) ; 41 | } 42 | 43 | return value ; 44 | } 45 | 46 | void shiftOut(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder, uint8_t ulVal) 47 | { 48 | uint8_t i ; 49 | 50 | for (i = 0 ; i < 8 ; i++) { 51 | if (ulBitOrder == LSBFIRST) { 52 | digitalWrite(ulDataPin, !!(ulVal & (1 << i))) ; 53 | } else { 54 | digitalWrite(ulDataPin, !!(ulVal & (1 << (7 - i)))) ; 55 | } 56 | 57 | digitalWrite(ulClockPin, HIGH) ; 58 | digitalWrite(ulClockPin, LOW) ; 59 | } 60 | } 61 | 62 | #ifdef __cplusplus 63 | } // extern "C" 64 | #endif 65 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.https://www.sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/source/_static/install_preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/install_preferences.png -------------------------------------------------------------------------------- /docs/source/_static/install_sg200x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/install_sg200x.png -------------------------------------------------------------------------------- /docs/source/_static/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/pin.png -------------------------------------------------------------------------------- /docs/source/_static/select_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/select_board.png -------------------------------------------------------------------------------- /docs/source/_static/select_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/select_example.png -------------------------------------------------------------------------------- /docs/source/_static/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milkv-duo/duo-arduino/7c3761bdbb70a1b86ac40b0391b60e9520555c52/docs/source/_static/upload.png -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | import sys, os 17 | import sphinx_rtd_theme 18 | 19 | # -- Project information ----------------------------------------------------- 20 | 21 | project = 'arduino-sophgo' 22 | copyright = '2024, sophgo' 23 | author = 'sophgo' 24 | 25 | # The full version, including alpha/beta/rc tags 26 | # release = 'X.X.X' 27 | 28 | 29 | # -- General configuration --------------------------------------------------- 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = [ 35 | ] 36 | 37 | # Add any paths that contain templates here, relative to this directory. 38 | 39 | templates_path = ['_templates'] 40 | 41 | language = 'zh_CN' 42 | 43 | # List of patterns, relative to source directory, that match files and 44 | # directories to ignore when looking for source files. 45 | # This pattern also affects html_static_path and html_extra_path. 46 | exclude_patterns = [] 47 | 48 | 49 | # -- Options for HTML output ------------------------------------------------- 50 | 51 | # The theme to use for HTML and HTML Help pages. See the documentation for 52 | # a list of builtin themes. 53 | # 54 | # html_theme = 'alabaster' 55 | 56 | # Add any paths that contain custom static files (such as style sheets) here, 57 | # relative to this directory. They are copied after the builtin static files, 58 | # so a file named "default.css" will overwrite the builtin "default.css". 59 | html_theme = "sphinx_rtd_theme" 60 | html_static_path = ['_static'] 61 | -------------------------------------------------------------------------------- /docs/source/examples.rst: -------------------------------------------------------------------------------- 1 | ######### 2 | 示例文档 3 | ######### 4 | 5 | arduino-sg200x 提供了一些示例代码, 以下是使用Arduino Core for Sg200x使用的代码: 6 | 7 | #. pin定义。 8 | 9 | .. figure:: ./_static/pin.png 10 | :align: center 11 | :figclass: align-center 12 | 13 | .. toctree:: 14 | :maxdepth: 1 15 | :glob: 16 | 17 | examples/* 18 | -------------------------------------------------------------------------------- /docs/source/examples/led.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | LED示例 3 | ############ 4 | 5 | 6 | 示例代码: 7 | :: 8 | 9 | #define TEST_PIN 2 10 | // the setup function runs once when you press reset or power the board 11 | void setup() { 12 | pinMode(TEST_PIN, OUTPUT); 13 | } 14 | 15 | // the loop function runs over and over again forever 16 | void loop() { 17 | digitalWrite(TEST_PIN, HIGH); // turn the LED on (HIGH is the voltage level) 18 | delay(500); // wait for a second 19 | digitalWrite(TEST_PIN, LOW); // turn the LED off by making the voltage LOW 20 | delay(500); // wait for a second 21 | } 22 | -------------------------------------------------------------------------------- /docs/source/get-started/getting-started.rst: -------------------------------------------------------------------------------- 1 | ###### 2 | 开始 3 | ###### 4 | 5 | 6 | 关于Arduino 7 | ################## 8 | 9 | 简介 10 | ======= 11 | 12 | Arduino是一款便捷灵活、方便上手的开源电子原型平台。\ 13 | 包含硬件(各种型号的Arduino板)和软件(ArduinoIDE)。由一个欧洲开发团队于2005年冬季开发。\ 14 | 其成员包括Massimo Banzi、David Cuartielles、Tom Igoe、Gianluca Martino、David Mellis和Nicholas Zambetti等。 15 | 16 | 它构建于开放原始码simple I/O介面版,并且具有使用类似Java、C语言的Processing/Wiring开发环境。\ 17 | 主要包含两个部分:硬件部分是可以用来做电路连接的Arduino电路板;另外一个则是Arduino IDE,你的计算机中的程序开发环境。\ 18 | 你只要在IDE中编写程序代码,将程序上传到Arduino电路板后,程序便会告诉Arduino电路板要做些什么了。 19 | 20 | Arduino能通过各种各样的传感器来感知环境,通过控制灯光、马达和其他的装置来反馈、影响环境。\ 21 | 板子上的微控制器可以通过Arduino的编程语言来编写程序,编译成二进制文件,烧录进微控制器。\ 22 | 对Arduino的编程是通过 Arduino编程语言 (基于 Wiring)和Arduino开发环境(基于 Processing)来实现的。\ 23 | 基于Arduino的项目,可以只包含Arduino,也可以包含Arduino和其他一些在PC上运行的软件,它们之间进行通信 (比如 Flash, Processing, MaxMSP)来实现。 24 | 25 | 26 | Arduino特性: 27 | ================== 28 | 29 | - 跨平台 30 | 31 | Arduino IDE可以在Windows、Macintosh OS(Mac OS)、Linux三大主流操作系统上运行,而其他的大多数控制器只能在Windows上开发。 32 | 33 | - 简单清晰 34 | 35 | Arduino IDE基于processing IDE开发。对于初学者来说,极易掌握,同时有着足够的灵活性。\ 36 | Arduino语言基于wiring语言开发,是对 avr-gcc库的二次封装,不需要太多的单片机基础、编程基础,简单学习后,你也可以快速的进行开发。 37 | 38 | - 开放性 39 | 40 | Arduino的硬件原理图、电路图、IDE软件及核心库文件都是开源的,在开源协议范围内里可以任意修改原始设计及相应代码。 41 | 42 | - 发展迅速 43 | 44 | Arduino不仅仅是全球最流行的开源硬件,也是一个优秀的硬件开发平台,更是硬件开发的趋势。\ 45 | Arduino简单的开发方式使得开发者更关注创意与实现,更快的完成自己的项目开发,大大节约了学习的成本,缩短了开发的周期。\ 46 | 因为Arduino的种种优势,越来越多的专业硬件开发者已经或开始使用Arduino来开发他们的项目、产品;\ 47 | 越来越多的软件开发者使用Arduino进入硬件、物联网等开发领域;大学课题,自动化、软件,甚至艺术专业,也纷纷开展了Arduino相关课程。 48 | 49 | 50 | Arduino Sg200x 51 | ################## 52 | 53 | 该项目是为Sg200x支持Arduino而建立,可以适配绝大多数Arduino的API, 要查看 Arduino 参考文档, 请考虑阅读官方文档。 54 | 55 | Arduino官方文档:Arduino参考_。 56 | 57 | Arduino Sg200x模块的API文档位于 API文档_ 。 58 | 59 | 60 | Arduino Sg200x项目源码地址:https://github.com/xxx/arduino-sophgo。 61 | 62 | 63 | .. _Arduino参考: https://www.arduino.cc/reference/en/ 64 | 65 | .. _API文档: ../libraries.html 66 | 67 | -------------------------------------------------------------------------------- /docs/source/get-started/quick-guides.rst: -------------------------------------------------------------------------------- 1 | ######## 2 | 快速上手 3 | ######## 4 | 5 | 本篇将说明如何安装 Arduino-Sg200x 支持,以及如何快速使用。 6 | 7 | 安装Arduino IDE 8 | ################## 9 | 10 | 执行以下步骤: 11 | 12 | #. Arduino IDE支持Windows,Linux, macOS三种操作系统,根据你的系统到 arduino.cc网站_ 下载对应安装包进行安装,建议使用1.8.X以上版本。 13 | 14 | #. 启动Arduino并打开 ``文件`` > ``首选项`` 窗口。 15 | 16 | .. figure:: ../_static/install_preferences.png 17 | :align: center 18 | :width: 600 19 | :figclass: align-center 20 | 21 | #. 在 ``附加开发板管理器网址:`` 字段中输入以下版本链接之一。您可以添加多个URL,并用逗号分隔它们。 22 | 23 | - Stable release link:: 24 | 25 | https://127.0.0.1/package_sg200x_index.json 26 | 27 | 28 | #. 从 ``工具`` > ``开发板`` 菜单中打开 ``开发板管理器`` 并安装 *SG200X* 平台。 29 | 30 | .. figure:: ../_static/install_sg200x.png 31 | :align: center 32 | :width: 600 33 | :figclass: align-center 34 | 35 | 36 | #. 安装后不要忘记从 ``工具`` > ``开发板`` 菜单中选择您的 *SG200X* 开发板。 37 | 38 | .. figure:: ../_static/select_board.png 39 | :align: center 40 | :width: 600 41 | :figclass: align-center 42 | 43 | 44 | 到此Arduino Sg200x开发环境便已经安装完成,下面就可以尝试简单使用下了。 45 | 46 | 使用 47 | ########## 48 | 49 | 运行一个示例 50 | ============= 51 | 52 | #. 将Duo板子插入到电脑USB 53 | 54 | 55 | #. 打开 ``文件`` > ``示例`` 找到Duo的例子,选择 ``01.Basics`` > ``Blink`` ,该示例演示了控制led闪烁。 56 | 57 | .. figure:: ../_static/select_example.png 58 | :align: center 59 | :width: 400 60 | :figclass: align-center 61 | 62 | 63 | #. 点击 ``上传`` 按钮,会执行编译并烧录程序到板子。 64 | 65 | .. figure:: ../_static/upload.png 66 | :align: center 67 | :width: 700 68 | :figclass: align-center 69 | 70 | 出现上传成功提示,就可以看到板子上的led在闪烁了。到此为止就完成了示例代码的运行演示。 71 | 72 | 如果想要自己在示例代码基础上修改,可以点击 ``保存`` 按钮,把代码保存到自己的项目路径下,然后在进行修改编译上传。 73 | 74 | 75 | 社区库使用 76 | ============= 77 | 78 | 我们知道Arduino之所以成功正是因为它有众多社区提供的三方库,使用三方库可以大大简化我们的开发工作量,快速实现想要的功能。 79 | 80 | #. 从 ``工具`` > ``管理库`` 菜单中打开 ``库管理器`` ,在搜索框直接搜索想要找的库,例如 ``Adafruit GFX`` 。找到后安装即可。 81 | 82 | #. 从 ``项目`` > ``加载库`` 菜单中加载要使用的库,就会自动在代码编辑页面顶部加入该库的头文件,以便我们调用库的API。 83 | 84 | 85 | 编译好的二进制程序分发 86 | ========================= 87 | 88 | 如果你想把编译好程序的bin文件分享给他人使用,参考以下说明: 89 | 90 | * 点击 ``验证`` 或者 ``项目`` > ``验证/编译`` 按钮,确保程序可以正常编译。 91 | 92 | * 点击 ``项目`` > ``导出已编译的二进制文件`` 会将刚刚编好的bin文件导出到你的程序项目路径下。 93 | *注意:* 如果打开的是示例代码,则需要先保存项目文件到自己的项目路径下,才可以成功导出bin。 94 | 95 | 96 | .. _arduino.cc网站: https://www.arduino.cc/en/software 97 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to arduino-sophgo's documentation! 2 | ========================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | get-started/getting-started.rst 8 | get-started/quick-guides.rst 9 | libraries.rst 10 | examples.rst 11 | -------------------------------------------------------------------------------- /docs/source/libraries.rst: -------------------------------------------------------------------------------- 1 | ######### 2 | 库API文档 3 | ######### 4 | 5 | arduino-sg200x 提供了一些封装的模块, 以下是模块API说明: 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | :glob: 10 | 11 | libraries/* 12 | -------------------------------------------------------------------------------- /docs/source/libraries/adc.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | ADC 3 | ############ 4 | 5 | SARADC为模拟信号数字转换控制器。 6 | 7 | * Duo最多支持3个独立通道,但是当前仅对外提供通道1,对应于PIN_ADC1(编号31) 8 | 9 | * 支持12bit采样精度 10 | 11 | 使用请参考arduino官方文档: analogRead_ 和 analogReadResolution_: analogRead默认采用10bit采样,12bit硬件采样数据会映射到该位宽, 可通过analogReadResolution任意修改默认位宽,。 12 | 13 | 14 | .. _analogRead: https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/ 15 | 16 | .. _analogReadResolution: https://www.arduino.cc/reference/en/language/functions/analog-io/analogreadresolution/ 17 | 18 | 19 | 使用示例: 20 | :: 21 | 22 | int analogPin = PIN_ADC1; 23 | 24 | int val = 0; 25 | 26 | void setup() { 27 | Serial.begin(115200); // setup serial 28 | } 29 | 30 | void loop() { 31 | val = analogRead(analogPin); // read the input pin 32 | Serial.println(val); // debug value 33 | } 34 | -------------------------------------------------------------------------------- /docs/source/libraries/gpio.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | GPIO 3 | ############ 4 | 5 | Duo支持4组 GPIO (General Purpose Input/Output),GPIO0 ~ GPIO3。每组GPIO 提供 32 个可编程的输入输出管脚。 6 | 当前支持的外引脚包含如下PIN编号: 7 | 8 | * 0,1,2,(4,5,6,7,9,10,11,12),14,15,(16,17),19,20,21,22,24,25,26,27,(31,32) 9 | 10 | 不建议使用括号里面的PIN 11 | 12 | 13 | 相关API使用请参考arduino官方文档: 14 | 15 | * digital io操作: pinMode_, digitalRead_ 和 digitalWrite_ 16 | 17 | 当前不支持OUTPUT_OPENDRAIN模式 18 | 19 | .. _pinMode: https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/ 20 | 21 | .. _digitalRead: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/ 22 | 23 | .. _digitalWrite: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/ 24 | 25 | 使用示例: 26 | :: 27 | 28 | #define TEST_PIN 2 29 | // the setup function runs once when you press reset or power the board 30 | void setup() { 31 | pinMode(TEST_PIN, OUTPUT); 32 | } 33 | 34 | // the loop function runs over and over again forever 35 | void loop() { 36 | digitalWrite(TEST_PIN, HIGH); // turn the LED on (HIGH is the voltage level) 37 | delay(500); // wait for a second 38 | digitalWrite(TEST_PIN, LOW); // turn the LED off by making the voltage LOW 39 | delay(500); // wait for a second 40 | } 41 | 42 | * extenal interrupts操作: attachInterrupt_, detachInterrupt_ 和 digitalPinToInterrupt_。 43 | 44 | 当前支持LOW/HIGH/RISING/FALLING模式,并不支持CHANGE模式 45 | 46 | .. _attachInterrupt: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ 47 | 48 | .. _detachInterrupt: https://www.arduino.cc/reference/en/language/functions/external-interrupts/detachinterrupt/ 49 | 50 | .. _digitalPinToInterrupt: https://www.arduino.cc/reference/en/language/functions/external-interrupts/digitalpintointerrupt/ 51 | 52 | 使用示例: 53 | :: 54 | 55 | // connect ledPin and interruptPin 56 | const byte ledPin = 1; 57 | const byte interruptPin = 2; 58 | volatile byte state = HIGH; 59 | 60 | void setup() { 61 | Serial.begin(115200); 62 | pinMode(ledPin, OUTPUT); 63 | pinMode(interruptPin, INPUT_PULLUP); 64 | digitalWrite(ledPin, LOW); 65 | attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING); 66 | } 67 | 68 | void loop() { 69 | state = !state; 70 | digitalWrite(ledPin, state); 71 | delay(1000); 72 | } 73 | 74 | void blink() { 75 | Serial.printf("trigger interrupt\n\r"); 76 | } 77 | 78 | * 部分Advance io 操作: pulseIn_, pulseInLong_, shiftIn_, shiftOut_ 79 | 80 | .. _pulseIn: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/ 81 | 82 | .. _pulseInLong: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulseinlong/ 83 | 84 | .. _shiftIn: https://www.arduino.cc/reference/en/language/functions/advanced-io/shiftin/ 85 | 86 | .. _shiftOut: https://www.arduino.cc/reference/en/language/functions/advanced-io/shiftout/ 87 | 88 | 使用示例: 89 | :: 90 | 91 | /* 92 | * HC-SR04 example sketch 93 | * 94 | * https://create.arduino.cc/projecthub/Isaac100/getting-started-with-the-hc-sr04-ultrasonic-sensor-036380 95 | * 96 | * by Isaac100 97 | */ 98 | 99 | const int trigPin = 19; 100 | const int echoPin = 20; 101 | volatile byte state = HIGH; 102 | 103 | float duration, distance; 104 | 105 | void setup() { 106 | pinMode(trigPin, OUTPUT); 107 | pinMode(echoPin, INPUT); 108 | Serial.begin(115200); 109 | } 110 | 111 | void loop() { 112 | digitalWrite(trigPin, LOW); 113 | delayMicroseconds(2); 114 | digitalWrite(trigPin, HIGH); 115 | delayMicroseconds(10); 116 | digitalWrite(trigPin, LOW); 117 | 118 | duration = pulseIn(echoPin, HIGH); 119 | 120 | distance = (duration*.0343)/2; 121 | Serial.print("Distance: "); 122 | Serial.println(distance); 123 | delay(100); 124 | } 125 | -------------------------------------------------------------------------------- /docs/source/libraries/i2c.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | Wire/I2C 3 | ############ 4 | 5 | 该库用于与 `I2C/TWI` 设备进行通信。 6 | 7 | * Duo支持5个I2C总线。 8 | 9 | * 支持全引脚映射。 10 | 11 | 12 | 使用请参考arduino官方文档: Wire_。 13 | 14 | .. _Wire: https://www.arduino.cc/reference/en/language/functions/communication/wire/ 15 | 16 | 使用示例: 17 | :: 18 | 19 | #include 20 | 21 | void receive(int a) { 22 | Serial.printf("receive %d bytes\n\r", a); 23 | while(a--) { 24 | Serial.printf("%d \n\r", Wire1.read()); 25 | } 26 | } 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | Wire1.begin(0x50); 31 | Wire1.onReceive(receive); 32 | Wire.begin(); 33 | Serial.printf("test slave\n\r"); 34 | Wire1.print(); 35 | } 36 | 37 | byte val = 0; 38 | 39 | void loop() { 40 | // put your main code here, to run repeatedly: 41 | Wire.beginTransmission(0x50); 42 | Serial.printf("send %d \n\r", ++val); 43 | Wire.write(val); // Sends value byte 44 | Wire.endTransmission(); // Stop transmitting 45 | Wire1.onService(); 46 | } 47 | -------------------------------------------------------------------------------- /docs/source/libraries/mailbox.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | MAILBOX 3 | ############ 4 | 5 | Duo 提供1组8通道Mailbox,用于大核C906B和小核C906L间的通信 6 | 7 | 在大核上也就是Linux系统中,参考程序详见: rtoscore_ 8 | 9 | .. _rtoscore: https://milkv.io/docs/duo/getting-started/rtoscore 10 | 11 | 使用的消息结构体如下: 12 | 13 | :: 14 | 15 | struct valid_t { 16 | unsigned char linux_valid; 17 | unsigned char rtos_valid; 18 | } __attribute__((packed)); 19 | 20 | typedef union resv_t { 21 | struct valid_t valid; 22 | unsigned short mstime; // 0 : noblock, -1 : block infinite 23 | } resv_t; 24 | 25 | typedef struct cmdqu_t cmdqu_t; 26 | /* cmdqu size should be 8 bytes because of mailbox buffer size */ 27 | struct cmdqu_t { 28 | unsigned char ip_id; 29 | unsigned char cmd_id : 7; 30 | unsigned char block : 1; 31 | union resv_t resv; 32 | unsigned int param_ptr; 33 | } __attribute__((packed)) __attribute__((aligned(0x8))); 34 | 35 | 注意,接收到的消息要和 ``cmdqu_t`` 进行映射,才具有意义 36 | 37 | 在arduino中,实现了以下接口 38 | 39 | 描述 40 | ====== 41 | 42 | mailbox 初始化函数 43 | 44 | 语法 45 | ====== 46 | 47 | .. code-block:: arduino 48 | 49 | void mailbox_init (bool master); 50 | 51 | 参数 52 | ====== 53 | 54 | * ``master`` 是否进行硬件初始化,默认false 55 | 56 | 返回值 57 | ======== 58 | 59 | 无 60 | 61 | 描述 62 | ====== 63 | 64 | mailbox 回调函数注册 65 | 66 | 语法 67 | ====== 68 | 69 | .. code-block:: arduino 70 | 71 | void mailbox_register (int channel, void(*callback)(MailboxMsg)); 72 | 73 | 参数 74 | ====== 75 | 76 | * ``channel`` 注册的通道号 77 | 78 | * ``void(*callback)(MailboxMsg)`` 回调函数,参数为MailboxMsg对象 79 | 80 | 返回值 81 | ======== 82 | 83 | 无 84 | 85 | 描述 86 | ====== 87 | 88 | mailbox 回调函数取消注册 89 | 90 | 语法 91 | ====== 92 | 93 | .. code-block:: arduino 94 | 95 | void mailbox_unregister (int channel); 96 | 97 | 参数 98 | ====== 99 | 100 | * ``channel`` 取消注册的通道号 101 | 102 | 返回值 103 | ======== 104 | 105 | 无 106 | 107 | 描述 108 | ====== 109 | 110 | mailbox 使能接收通道 111 | 112 | 语法 113 | ====== 114 | 115 | .. code-block:: arduino 116 | 117 | void mailbox_enable_receive (int channel); 118 | 119 | 参数 120 | ====== 121 | 122 | * ``channel`` 通道号 123 | 124 | 返回值 125 | ======== 126 | 127 | 无 128 | 129 | 描述 130 | ====== 131 | 132 | mailbox 关闭使能接收通道 133 | 134 | 语法 135 | ====== 136 | 137 | .. code-block:: arduino 138 | 139 | void mailbox_disable_receive (int channel); 140 | 141 | 参数 142 | ====== 143 | 144 | * ``channel`` 通道号 145 | 146 | 返回值 147 | ======== 148 | 149 | 无 150 | 151 | 描述 152 | ====== 153 | 154 | mailbox 发送消息 155 | 156 | 语法 157 | ====== 158 | 159 | .. code-block:: arduino 160 | 161 | void mailbox_write(MailboxMsg& msg); 162 | 163 | 参数 164 | ====== 165 | 166 | * ``msg`` 需要写入的消息和通道 167 | 168 | 返回值 169 | ======== 170 | 171 | 无 172 | 173 | 174 | 175 | 176 | 使用示例: 177 | 178 | :: 179 | 180 | #include "mailbox.h" 181 | 182 | void showmsg(MailboxMsg msg) 183 | { 184 | Serial2.print("showmsg: "); 185 | Serial2.println(*(msg.data), HEX); 186 | *(msg.data) = 0; //消息接收后需要手动清空 187 | } 188 | 189 | void setup() { 190 | // put your setup code here, to run once: 191 | Serial2.begin(115200); 192 | mailbox_init (false); 193 | mailbox_register (0, showmsg); 194 | mailbox_enable_receive (0); 195 | } 196 | 197 | void loop() { 198 | // put your main code here, to run repeatedly: 199 | 200 | } -------------------------------------------------------------------------------- /docs/source/libraries/pwm.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | PWM 3 | ############ 4 | 5 | Duo提供1组4路独立的PWM信号输出。4路PWM皆可独立操作: 6 | 7 | * 内部有30-bit计数器,输出周期和高/低电平拍数皆可配置 8 | 9 | * 支持最高50MHz (100MHz/2) 或 74.25MHz (148.5MHz/2) 输出,最低约0.093Hz (100MHz/(2^30-1)) 或 0.138Hz (148.5MHz/(2^32-1)) 10 | 11 | * 支持连续输出(PWMMODE = 0)和固定脉冲个数输出(PWMMODE = 1)两种模式 12 | 13 | 14 | 目前支持的PWM对外引脚包括如下PIN编号: 15 | 16 | * 4, 5, (6, 7), 9, 10, 11, (12, 16, 17, 31), 32 17 | 18 | 不建议使用括号里面的PIN 19 | 20 | 21 | 相关API使用请参考arduino官方文档: 22 | 23 | * 部分analog io操作: analogWrite_ 和 analogWriteResolution_ 24 | 25 | .. _analogWrite: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/ 26 | 27 | .. _analogWriteResolution: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwriteresolution/ 28 | 29 | 使用示例: 30 | :: 31 | 32 | // sg90 5V 33 | void setup() { 34 | analogWriteResolution(14); // 20ms 35 | } 36 | 37 | void loop() { 38 | analogWrite(4, 500); 39 | delay(1000); 40 | analogWrite(4, 1000); 41 | delay(1000); 42 | analogWrite(4, 1500); 43 | delay(1000); 44 | analogWrite(4, 2000); 45 | delay(1000); 46 | analogWrite(4, 2500); 47 | delay(1000); 48 | } 49 | 50 | 51 | 52 | * 部分Advance io 操作: tone_ 和 noTone_ 53 | 54 | .. _tone: https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/ 55 | 56 | .. _noTone: https://www.arduino.cc/reference/en/language/functions/advanced-io/notone/ 57 | 58 | 使用示例: 59 | :: 60 | 61 | void setup() { 62 | tone(4, 1000); // 1K Hz 63 | tone(5, 1000); // will be ignored 64 | delay(2000); 65 | noTone(4); 66 | tone(5, 1000, 1000000); // duration 1s 67 | delay(2000); 68 | noTone(5); 69 | } 70 | 71 | void loop() { 72 | } 73 | 74 | -------------------------------------------------------------------------------- /docs/source/libraries/serial.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | UART 3 | ############ 4 | 5 | UART(Universal Asynchronous Receiver Transmitter)是一个异步串行的通信接口,主要功能是将来自外围设备的资料进行串并转换之后传入内部总线,以及将资料进行并串转换之后输出到外部设备。UART 的主要功能是和外部芯片的UART进行对接,从而实现两芯片间的通信。 6 | 7 | Duo提供5个UART控制器,对应于5个全局Serial实例: Serial0~5,它们对应的默认PIN如下: 8 | 9 | +--------+--------+----------+ 10 | |实例 | RX | TX | 11 | +--------+--------+----------+ 12 | |Serial0 | 17 | 16 | 13 | +--------+--------+----------+ 14 | |Serial1 | 2 | 1 | 15 | +--------+--------+----------+ 16 | |Serial2 | 7 | 6 | 17 | +--------+--------+----------+ 18 | |Serial3 | 7 | 6 | 19 | +--------+--------+----------+ 20 | |Serial4 | 5 | 4 | 21 | +--------+--------+----------+ 22 | 23 | 默认的调试接口: Serial => Serial3。 24 | 25 | 对于RX/TX重叠的Serial可以交替使用(使用之前通过begin接口使能)。 26 | 27 | 相关API使用请参考arduino官方文档: Serial_。 28 | 29 | .. _Serial: https://www.arduino.cc/reference/en/language/functions/communication/serial/ 30 | 31 | 32 | 使用示例: 33 | :: 34 | 35 | void setup() { 36 | Serial2.begin(115200); 37 | } 38 | 39 | bool select = true; 40 | void loop() { 41 | 42 | //read from port 2, send to port 3: 43 | if (select && Serial2.available()) { 44 | int inByte = Serial2.read(); 45 | Serial3.begin(115200); 46 | Serial3.printf("From 2: %c \n", inByte); 47 | int i = 0; 48 | while(Serial2.available()) { 49 | inByte = Serial2.read(); 50 | Serial3.printf(" -- %d: ", i++); 51 | Serial3.write(inByte); 52 | } 53 | Serial3.printf("2 Msg end\n"); 54 | select = false; 55 | } 56 | 57 | //read from port 3, send to port 2: 58 | if (!select && Serial3.available()) { 59 | int inByte = Serial3.read(); 60 | Serial2.begin(115200); 61 | Serial2.printf("From 3: %c \n", inByte); 62 | int i = 0; 63 | while(Serial3.available()) { 64 | inByte = Serial3.read(); 65 | Serial2.printf(" -- %d: ", i++); 66 | Serial2.write(inByte); 67 | } 68 | Serial2.printf("3 Msg end\n"); 69 | select = true; 70 | } 71 | } 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/source/libraries/spi.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | SPI 3 | ############ 4 | 5 | * 对外开放两个spi总线,且SPI0默认用作lcd驱动。 6 | 7 | * SPI支持全引脚映射。 8 | 9 | * 暂不支持从机。 10 | 11 | 使用请参考arduino官方文档: SPI_。 12 | 13 | 14 | .. _SPI: https://www.arduino.cc/reference/en/language/functions/communication/spi/ 15 | 16 | 使用示例: 17 | :: 18 | 19 | #include 20 | 21 | char in_byte = 3; 22 | 23 | void setup() { 24 | // put your setup code here, to run once: 25 | Serial.begin(115200); 26 | SPI.begin(); 27 | } 28 | 29 | void loop() { 30 | // put your main code here, to run repeatedly: 31 | SPI.beginTransaction(SPISettings()); 32 | char out_byte = SPI.transfer(in_byte); // spi loop back 33 | SPI.endTransaction(); 34 | Serial.printf("receive %x\n\r", out_byte); 35 | } 36 | -------------------------------------------------------------------------------- /libraries/SPI/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SPI 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SPI KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | end KEYWORD2 16 | transfer KEYWORD2 17 | setBitOrder KEYWORD2 18 | setDataMode KEYWORD2 19 | setClockDivider KEYWORD2 20 | 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | SPI_CLOCK_DIV4 LITERAL1 26 | SPI_CLOCK_DIV16 LITERAL1 27 | SPI_CLOCK_DIV64 LITERAL1 28 | SPI_CLOCK_DIV128 LITERAL1 29 | SPI_CLOCK_DIV2 LITERAL1 30 | SPI_CLOCK_DIV8 LITERAL1 31 | SPI_CLOCK_DIV32 LITERAL1 32 | SPI_CLOCK_DIV64 LITERAL1 33 | SPI_MODE0 LITERAL1 34 | SPI_MODE1 LITERAL1 35 | SPI_MODE2 LITERAL1 36 | SPI_MODE3 LITERAL1 -------------------------------------------------------------------------------- /libraries/SPI/library.properties: -------------------------------------------------------------------------------- 1 | name=SPI 2 | version=1.0.0 3 | author= 4 | maintainer= 5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For Duo, BUT Arduino DUE. 6 | paragraph= 7 | category=Signal Input/Output 8 | url=http://arduino.cc/en/Reference/SPI 9 | architectures=SG200X 10 | -------------------------------------------------------------------------------- /libraries/SPI/src/SPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPI.h - SPI library for esp32 3 | 4 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef _SPI_H_INCLUDED 22 | #define _SPI_H_INCLUDED 23 | 24 | #include "common.h" 25 | #include "csi_spi.h" 26 | 27 | #define SPI_HAS_TRANSACTION 28 | 29 | typedef enum { 30 | SPI_MODE0 = SPI_FORMAT_CPOL0_CPHA0, 31 | SPI_MODE1 = SPI_FORMAT_CPOL0_CPHA1, 32 | SPI_MODE2 = SPI_FORMAT_CPOL1_CPHA0, 33 | SPI_MODE3 = SPI_FORMAT_CPOL1_CPHA1, 34 | } SPIMode; 35 | 36 | typedef enum { 37 | SPI_LSBFIRST, 38 | SPI_MSBFIRST 39 | } SPIBitOrder; 40 | 41 | class SPISettings 42 | { 43 | public: 44 | SPISettings() :_clock(1000000), _bitOrder(SPI_MSBFIRST), _dataMode(SPI_MODE0) {} 45 | SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) :_clock(clock), _bitOrder(bitOrder), _dataMode(dataMode) {} 46 | uint32_t _clock; 47 | uint8_t _bitOrder; 48 | uint8_t _dataMode; 49 | }; 50 | 51 | class SPIClass 52 | { 53 | public: 54 | SPIClass(uint8_t spiBus = 2); 55 | ~SPIClass(); 56 | 57 | /// @brief SPI begin 58 | /// @param sckPin Spi SCLK pin 59 | /// @param misoPin Spi MISO pin, -1 not used 60 | /// @param mosiPin Spi MOSI pin 61 | /// @param csPin Spi CS pin, -1 not used 62 | void begin(int8_t sckPin, int8_t misoPin, int8_t mosiPin, int8_t csPin); 63 | inline void begin() 64 | { 65 | return begin( PIN_SPI2_SCK, PIN_SPI2_MISO, PIN_SPI2_MOSI, PIN_SPI2_CS); 66 | } 67 | void end(); 68 | 69 | void setBitOrder(uint8_t bitOrder); 70 | void setDataMode(uint8_t dataMode); 71 | void setFrequency(uint32_t freq); 72 | 73 | void beginTransaction(SPISettings settings); 74 | void endTransaction(void); 75 | void transfer(void * data, uint32_t size); 76 | uint8_t transfer(uint8_t data); 77 | uint16_t transfer16(uint16_t data); 78 | 79 | void transferBytes(void* data, void* out, uint32_t size); 80 | 81 | private: 82 | uint8_t _idx; 83 | bool _initialized; 84 | 85 | csi_spi_t _spiBus; 86 | 87 | csi_dma_ch_t tx_dma; 88 | csi_dma_ch_t rx_dma; 89 | 90 | volatile uint8_t spi_flag = 0; 91 | 92 | int8_t _sckPin, _mosiPin, _misoPin, _csPin; 93 | 94 | bool _inTransaction; 95 | bool _lock; 96 | 97 | 98 | SPISettings _setting; 99 | }; 100 | 101 | extern SPIClass SPI; 102 | 103 | #endif /* _SPI_H_INCLUDED */ 104 | -------------------------------------------------------------------------------- /libraries/Wire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | begin KEYWORD2 14 | end KEYWORD2 15 | setClock KEYWORD2 16 | beginTransmission KEYWORD2 17 | endTransmission KEYWORD2 18 | requestFrom KEYWORD2 19 | onReceive KEYWORD2 20 | onRequest KEYWORD2 21 | 22 | ####################################### 23 | # Instances (KEYWORD2) 24 | ####################################### 25 | 26 | Wire KEYWORD2 27 | TwoWire KEYWORD2 28 | 29 | ####################################### 30 | # Constants (LITERAL1) 31 | ####################################### 32 | 33 | HARDWARE_I2C_BUFF_LEN LITERAL1 -------------------------------------------------------------------------------- /libraries/Wire/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire 2 | version=1.0.0 3 | author= 4 | maintainer= 5 | sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For Duo boards. 6 | paragraph= 7 | category=Signal Input/Output 8 | url=http://arduino.cc/en/Reference/Wire 9 | architectures=SG200X 10 | -------------------------------------------------------------------------------- /libraries/Wire/src/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "Arduino.h" 22 | #include 23 | #include "Stream.h" 24 | #include "csi_iic.h" 25 | #include "RingBuffer.h" 26 | 27 | // namespace arduino { 28 | 29 | #define HARDWARE_I2C_BUFF_LEN (64) 30 | 31 | typedef void(*user_onRequest)(void); 32 | typedef void(*user_onReceive)(uint8_t*, int); 33 | 34 | class TwoWire : public Stream 35 | { 36 | public: 37 | TwoWire(uint8_t idx, uint8_t pinSDA, uint8_t pinSCL); 38 | void begin(csi_iic_addr_mode_t addr_mode = IIC_ADDRESS_7BIT); 39 | void begin(uint16_t address, csi_iic_addr_mode_t addr_mode = IIC_ADDRESS_7BIT); 40 | 41 | void end(); 42 | void setClock(uint32_t); 43 | 44 | void beginTransmission(uint16_t); 45 | uint8_t endTransmission(bool stopBit); 46 | uint8_t endTransmission(void); 47 | 48 | size_t requestFrom(uint16_t address, size_t quantity, bool stopBit); 49 | size_t requestFrom(uint16_t address, size_t quantity); 50 | 51 | size_t write(uint8_t data); 52 | size_t write(const uint8_t * data, size_t quantity); 53 | 54 | virtual int available(void); 55 | virtual int read(void); 56 | virtual int peek(void); 57 | virtual void flush(void); 58 | void onReceive(void(*)(int)); 59 | void onRequest(void(*)(void)); 60 | 61 | void print(void); 62 | 63 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 64 | inline size_t write(long n) { return write((uint8_t)n); } 65 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 66 | inline size_t write(int n) { return write((uint8_t)n); } 67 | void setWireTimeout(uint64_t timeout, bool reset_on_timeout) { _timeout = timeout / 1000; } 68 | using Print::write; 69 | 70 | void onService(void); 71 | 72 | private: 73 | csi_iic_t _iic; 74 | uint8_t _uc_pinSDA; 75 | uint8_t _uc_pinSCL; 76 | uint8_t _idx; 77 | uint16_t _addr; 78 | uint64_t _timeout; 79 | bool _master; 80 | 81 | bool transmissionBegun; 82 | 83 | // RX Buffer 84 | RingBufferN<256> rxBuffer; 85 | 86 | //TX buffer 87 | RingBufferN<256> txBuffer; 88 | uint8_t txAddress; 89 | 90 | // Callback user functions 91 | void (*onRequestCallback)(void); 92 | void (*onReceiveCallback)(int); 93 | 94 | // TWI clock frequency 95 | static const uint32_t TWI_CLOCK = 100000; 96 | }; 97 | 98 | #if WIRE_INTERFACES_COUNT > 0 99 | extern TwoWire Wire0; 100 | #endif 101 | #if WIRE_INTERFACES_COUNT > 1 102 | extern TwoWire Wire1; 103 | #endif 104 | #if WIRE_INTERFACES_COUNT > 2 105 | extern TwoWire Wire2; 106 | #endif 107 | #if WIRE_INTERFACES_COUNT > 3 108 | extern TwoWire Wire3; 109 | #endif 110 | #if WIRE_INTERFACES_COUNT > 4 111 | extern TwoWire Wire4; 112 | #endif 113 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "framework-arduino-sophgo", 3 | "description": "Arduino Wiring-based Framework (Sophgo Core)", 4 | "version": "0.2.4", 5 | "url": "https://github.com/milkv-duo/duo-arduino", 6 | "keywords": [ 7 | "framework", 8 | "arduino", 9 | "sophgo", 10 | "sg200x", 11 | "Duo", 12 | "Duo256" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /package/_vercmp.sh: -------------------------------------------------------------------------------- 1 | # _vercmp g|l|e STRING0 STRING1 2 | # 3 | # Compare the version numbers contained in the two strings to determine their precedence 4 | # according to the specifications defined in https://semver.org/spec/v2.0.0.html 5 | # The build metadata will be ignored. 6 | # 7 | # options: 8 | # 9 | # g: compare if the version contained in STRING0 is greater than the version in STRING1 10 | # l: compare if the version contained in STRING0 is less than the version in STRING1 11 | # e: compare if the version contained in STRING0 is equal to the version in STRING1 12 | # 13 | # The return code is 14 | # 15 | # 0: when the above comparison holds 16 | # 1: when the above comparison does not hold 17 | # 18 | [[ -z ${_BASHFUNC_VERCMP} ]] || return 0 19 | _BASHFUNC_VERCMP=1 20 | 21 | __bashfunc_vercmp_compare_ver() { 22 | local v0=${1} v1=${2} is_num=1 res= prefix= v0_tmp=0 23 | if [[ $v0 =~ ^([[:alpha:]]+)([[:digit:]]+)$ ]]; then 24 | prefix="${BASH_REMATCH[1]}" 25 | v0_tmp="${BASH_REMATCH[2]}" 26 | if [[ ${v1#$prefix} =~ ^([[:digit:]]*)$ ]]; then 27 | v0="$v0_tmp" 28 | v1="${BASH_REMATCH[1]}" 29 | : "${v1:=-1}" 30 | fi 31 | fi 32 | if [[ ! ${v0} =~ ^[0-9]+$ ]] || [[ ! ${v1} =~ ^[0-9]+$ ]]; then 33 | is_num=0 34 | : ${v0/-1/\\/} 35 | : ${v1/-1/\\/} 36 | fi 37 | if [[ ${is_num} == 1 ]]; then 38 | if (( ${v0} > ${v1} )); then 39 | res="g" 40 | elif (( ${v0} == ${v1} )); then 41 | res="e" 42 | elif (( ${v0} < ${v1} )); then 43 | res="l" 44 | fi 45 | else 46 | if [[ ${v0} > ${v1} ]]; then 47 | res="g" 48 | elif [[ ${v0} == ${v1} ]]; then 49 | res="e" 50 | elif [[ ${v0} < ${v1} ]]; then 51 | res="l" 52 | fi 53 | fi 54 | echo -n "${res}" 55 | } 56 | __bashfunc_vercmp_compare() { 57 | local v0 v1 vv0 vv1 len res 58 | OIFS=$IFS; IFS="." 59 | v0=(${1}) v1=(${2}) 60 | IFS=$OIFS 61 | if [[ ${#v0[@]} -ge ${#v1[@]} ]]; then 62 | len=${#v0[@]} 63 | else 64 | len=${#v1[@]} 65 | fi 66 | for (( i=0; i<${len}; i++ )); do 67 | vv0=${v0[$i]:--1} 68 | vv1=${v1[$i]:--1} 69 | res=$(__bashfunc_vercmp_compare_ver ${vv0} ${vv1}) 70 | if [[ ${res} != "e" ]]; then 71 | break 72 | fi 73 | done 74 | echo -n "${res}" 75 | } 76 | _vercmp() { 77 | local LC_ALL=C 78 | local action result 79 | case ${1} in 80 | g|l|e) 81 | action="${1}" 82 | ;; 83 | *) 84 | echo "internal function error: _vercmp, unexpected argument '${1}'" >&2 85 | return 1 86 | ;; 87 | esac 88 | shift 89 | 90 | local -a str0 str1 91 | local str0_pkgname str0_ver str0_pre 92 | local str1_pkgname str1_ver str1_pre 93 | 94 | OIFS=$IFS; IFS="-" 95 | str0=( $1 ) str1=( $2 ) 96 | IFS=$OIFS 97 | 98 | for _str in "str0" "str1"; do 99 | local _strA="${_str}[@]" _strV="${_str}_ver" _strP="${_str}_pre" _strN="${_str}_pkgname" 100 | for _s in "${!_strA}"; do 101 | if [[ -n ${!_strV} ]]; then 102 | eval "${_str}_pre=\"${_s}\"" 103 | elif [[ ${_s} =~ ^[vV]?[0-9]+\.? ]]; then 104 | _s="${_s#v}" 105 | eval "${_str}_ver=\"${_s#V}\"" 106 | else 107 | if [[ -n ${!_strN} ]]; then 108 | eval "${_str}_pkgname+=\"-\"" 109 | fi 110 | eval "${_str}_pkgname+=\"${_s}\"" 111 | fi 112 | done 113 | done 114 | 115 | if [[ ${str0_pkgname} != ${str1_pkgname} ]]; then 116 | echo "internal function error: _vercmp, compare with different package names '${str0_pkgname}', '${str1_pkgname}'" >&2 117 | return 99 118 | fi 119 | 120 | result=$(__bashfunc_vercmp_compare ${str0_ver} ${str1_ver}) 121 | if [[ ${result} == "e" ]]; then 122 | result=$(__bashfunc_vercmp_compare ${str0_pre:-zzzz} ${str1_pre:-zzzz}) 123 | fi 124 | 125 | if [[ ${result} == ${action} ]]; then 126 | return 0 127 | else 128 | return 1 129 | fi 130 | } 131 | 132 | # vim:sw=8:ts=8:noexpandtab 133 | -------------------------------------------------------------------------------- /package/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "basicInfo": { 3 | "repoOwner": "milkv-duo", 4 | "repoName": "duo-arduino", 5 | "downloadUrlFmt": "https://github.com/@REPOOWNER@/@REPONAME@/releases/download/@VERSION@/@ARCHIVENAME@", 6 | "indexJsonFileName": "package_sg200x_index.json", 7 | "milkvDuoIndexJsonFileReleaseTag": "config", 8 | "milkvDuoIndexJsonFileUrl": "https://github.com/milkv-duo/duo-arduino/releases/download/config/package_sg200x_index.json", 9 | "versionPrefix": "v" 10 | }, 11 | "ignoredVersions": [], 12 | "current": { 13 | "name": "SG200X", 14 | "architecture": "SG200X", 15 | "version": "0.2.4", 16 | "category": "SG200X", 17 | "archiveFileName": "arduino-sophgo.zip", 18 | "help": { 19 | "online": "https://community.milkv.io/" 20 | }, 21 | "boards": [ 22 | { 23 | "name": "Milkv Duo Dev Board" 24 | } 25 | ], 26 | "toolsDependencies": [ 27 | { 28 | "packager": "sophgo", 29 | "name": "xpack-riscv-none-elf-gcc", 30 | "version": "13.2.0-2", 31 | "source": "external", 32 | "systems": [ 33 | { 34 | "host": "i686-mingw32", 35 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-win32-x64.zip", 36 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-win32-x64.zip", 37 | "checksum": "SHA-256:28ce9f0cfa09f8d4c638a59fb4e17e3f61c80c47e46f11b2ba505a2a3db602f8", 38 | "size": "575804723" 39 | }, 40 | { 41 | "host": "x86_64-mingw32", 42 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-win32-x64.zip", 43 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-win32-x64.zip", 44 | "checksum": "SHA-256:28ce9f0cfa09f8d4c638a59fb4e17e3f61c80c47e46f11b2ba505a2a3db602f8", 45 | "size": "575804723" 46 | }, 47 | { 48 | "host": "x86_64-linux-gnu", 49 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", 50 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", 51 | "checksum": "SHA-256:52545afb900200fbf65fe05f7ce7090b8a42c64091f4f5d43cae6bb68ea2434a", 52 | "size": "514514778" 53 | }, 54 | { 55 | "host": "x86_64-apple-darwin", 56 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-darwin-x64.tar.gz", 57 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-darwin-x64.tar.gz", 58 | "checksum": "SHA-256:72e65bcad6360eb059096a0fb77f3e3e6c618b1281b89648056c95d1b2749466", 59 | "size": "506786123" 60 | }, 61 | { 62 | "host": "arm64-apple-darwin", 63 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-darwin-arm64.tar.gz", 64 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-darwin-arm64.tar.gz", 65 | "checksum": "SHA-256:dfe3123e5e5093b165eaaf18401b802cbb8697f5ec9b0f5cfd99c45e848fd8a7", 66 | "size": "503063487" 67 | }, 68 | { 69 | "host": "aarch64-linux-gnu", 70 | "archiveFileName": "xpack-riscv-none-elf-gcc-13.2.0-2-linux-arm64.tar.gz", 71 | "url": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-arm64.tar.gz", 72 | "checksum": "SHA-256:1c981c611a38dfe5af902089aed570d4dd501eb4ed88d801043e59ab9a62a86a", 73 | "size": "511508420" 74 | } 75 | ] 76 | }, 77 | { 78 | "packager": "sophgo", 79 | "name": "burntool_py", 80 | "version": "0.3", 81 | "source": "internal", 82 | "dir": "tools/burntool/", 83 | "excludePatterns": "", 84 | "systems": [ 85 | { 86 | "host": "i686-mingw32", 87 | "archiveFileName": "burntool.zip" 88 | }, 89 | { 90 | "host": "x86_64-mingw32", 91 | "archiveFileName": "burntool.zip" 92 | }, 93 | { 94 | "host": "x86_64-linux-gnu", 95 | "archiveFileName": "burntool.tar.gz" 96 | }, 97 | { 98 | "host": "x86_64-apple-darwin", 99 | "archiveFileName": "burntool.tar.gz" 100 | }, 101 | { 102 | "host": "arm64-apple-darwin", 103 | "archiveFileName": "burntool.tar.gz" 104 | }, 105 | { 106 | "host": "aarch64-linux-gnu", 107 | "archiveFileName": "burntool.tar.gz" 108 | } 109 | ] 110 | } 111 | ] 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /package/package_sg200x_index.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "sophgo", 5 | "maintainer": "Sophgo", 6 | "websiteURL": "https://github.com/milkv-duo/duo-arduino", 7 | "email": "global.support@sophgo.com", 8 | "help": { 9 | "online": "https://community.milkv.io/" 10 | }, 11 | "platforms": [], 12 | "tools": [] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /programmers.txt: -------------------------------------------------------------------------------- 1 | burntool.name=Burntool 2 | burntool.communication=serial 3 | burntool.protocol=serial 4 | burntool.program.protocol=serial 5 | burntool.program.tool=burntool_py 6 | burntool.program.tool.default=burntool_py 7 | burntool.program.extra_params= 8 | burntool.extra_params= 9 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.o 3 | cvi_updated 4 | -------------------------------------------------------------------------------- /tools/burntool/README.md: -------------------------------------------------------------------------------- 1 | ## BurnTool 2 | 3 | 当前版本V0.3 4 | 5 | ## 运行方法 6 | python burntool.py -p /dev/ttyUSB0 -f xxx.elf 7 | 8 | ``` 9 | 10 | usage: burntool [-h] [--chip CHIP] [--port PORT] [--baud BAUD] [--firmware FIRMWARE] 11 | 12 | burntool.py v0.3 - Burn Firmware Tool 13 | 14 | options: 15 | -h, --help show this help message and exit 16 | --chip CHIP, -c CHIP Target chip type 17 | --port PORT, -p PORT Serial port device 18 | --baud BAUD, -b BAUD Serial port baud rate used when flashing/reading 19 | --firmware FIRMWARE, -f FIRMWARE 20 | Firmware Files 21 | 22 | ``` -------------------------------------------------------------------------------- /variants/duo/link.ld: -------------------------------------------------------------------------------- 1 | /*******************************************************************/ 2 | /* */ 3 | /* This file is automatically generated by linker script generator.*/ 4 | /* */ 5 | /* Version: */ 6 | /* */ 7 | /* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */ 8 | /* */ 9 | /* Description : Cortex-A53 Linker Script */ 10 | /* */ 11 | /*******************************************************************/ 12 | OUTPUT_ARCH( "riscv" ) 13 | OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") 14 | 15 | _STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x20000; 16 | /*_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x1000000;*/ 17 | _HEAP_SIZE = 0x20000; 18 | 19 | _EL0_STACK_SIZE = DEFINED(_EL0_STACK_SIZE) ? _EL0_STACK_SIZE : 1024; 20 | _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 2048; 21 | _EL2_STACK_SIZE = DEFINED(_EL2_STACK_SIZE) ? _EL2_STACK_SIZE : 1024; 22 | 23 | /* Define Memories in the system */ 24 | 25 | MEMORY 26 | { 27 | psu_ddr_0_MEM_0 : ORIGIN = 0x83f40000 , LENGTH = 0xc0000 28 | } 29 | 30 | /* Specify the default entry point to the program */ 31 | 32 | /*ENTRY(_vector_table)*/ 33 | ENTRY(Reset_Handler) 34 | 35 | /* Define the sections, and where they are mapped in memory */ 36 | 37 | SECTIONS 38 | { 39 | .text : { 40 | KEEP (*(.vectors)) 41 | *(.boot) 42 | *(.text) 43 | *(.text.*) 44 | *(.gnu.linkonce.t.*) 45 | *(.plt) 46 | *(.gnu_warning) 47 | *(.gcc_execpt_table) 48 | *(.glue_7) 49 | *(.glue_7t) 50 | *(.ARM.extab) 51 | *(.gnu.linkonce.armextab.*) 52 | } > psu_ddr_0_MEM_0 53 | 54 | .init (ALIGN(64)) : { 55 | KEEP (*(.init)) 56 | } > psu_ddr_0_MEM_0 57 | 58 | .fini (ALIGN(64)) : { 59 | KEEP (*(.fini)) 60 | } > psu_ddr_0_MEM_0 61 | 62 | .interp : { 63 | KEEP (*(.interp)) 64 | } > psu_ddr_0_MEM_0 65 | 66 | .note-ABI-tag : { 67 | KEEP (*(.note-ABI-tag)) 68 | } > psu_ddr_0_MEM_0 69 | 70 | .rodata : { 71 | . = ALIGN(64); 72 | __rodata_start = .; 73 | *(.rodata) 74 | *(.rodata.*) 75 | *(.srodata*) 76 | *(.gnu.linkonce.r.*) 77 | __rodata_end = .; 78 | } > psu_ddr_0_MEM_0 79 | 80 | .rodata1 : { 81 | . = ALIGN(64); 82 | __rodata1_start = .; 83 | *(.rodata1) 84 | *(.rodata1.*) 85 | __rodata1_end = .; 86 | } > psu_ddr_0_MEM_0 87 | 88 | .rodata2 : { 89 | __init_array_start = .; 90 | __ctors_start__ = .; 91 | KEEP (*(SORT(.init_array.*))) 92 | KEEP (*(.init_array)) 93 | __init_array_end = .; 94 | __ctors_end__ = .; 95 | 96 | __fini_array_start = .; 97 | __dtors_start__ = .; 98 | KEEP (*(SORT(.fini_array.*))) 99 | KEEP (*(.fini_array)) 100 | __fini_array_end = .; 101 | __dtors_end__ = .; 102 | 103 | __ctor_start__ = .; 104 | KEEP (*(SORT(.ctors.*))) 105 | KEEP (*(.ctors)) 106 | __ctor_end__ = .; 107 | KEEP (*(SORT(.dtors.*))) 108 | KEEP (*(.dtors)) 109 | __dtor_end__ = .; 110 | . = ALIGN(0x8) ; 111 | } > psu_ddr_0_MEM_0 112 | 113 | .data : { 114 | . = ALIGN(64); 115 | _data = .; 116 | *(.data) 117 | *(.data.*) 118 | *(.sdata) 119 | *(.sdata.*) 120 | *(.gnu.linkonce.d.*) 121 | *(.jcr) 122 | *(.got) 123 | *(.got.plt) 124 | _edata = .; 125 | } > psu_ddr_0_MEM_0 126 | 127 | .data1 : { 128 | . = ALIGN(64); 129 | __data1_start = .; 130 | *(.data1) 131 | *(.data1.*) 132 | __data1_end = .; 133 | } > psu_ddr_0_MEM_0 134 | 135 | .resource_table : 136 | { 137 | KEEP(*(.resource_table)); 138 | } > psu_ddr_0_MEM_0 139 | 140 | .got : { 141 | *(.got) 142 | } > psu_ddr_0_MEM_0 143 | 144 | .got1 : { 145 | *(.got1) 146 | } > psu_ddr_0_MEM_0 147 | 148 | .got2 : { 149 | *(.got2) 150 | } > psu_ddr_0_MEM_0 151 | 152 | .ctors : { 153 | . = ALIGN(64); 154 | __CTOR_LIST__ = .; 155 | ___CTORS_LIST___ = .; 156 | KEEP (*crtbegin.o(.ctors)) 157 | KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) 158 | KEEP (*(SORT(.ctors.*))) 159 | KEEP (*(.ctors)) 160 | __CTOR_END__ = .; 161 | ___CTORS_END___ = .; 162 | } > psu_ddr_0_MEM_0 163 | 164 | .dtors : { 165 | . = ALIGN(64); 166 | __DTOR_LIST__ = .; 167 | ___DTORS_LIST___ = .; 168 | KEEP (*crtbegin.o(.dtors)) 169 | KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) 170 | KEEP (*(SORT(.dtors.*))) 171 | KEEP (*(.dtors)) 172 | __DTOR_END__ = .; 173 | ___DTORS_END___ = .; 174 | } > psu_ddr_0_MEM_0 175 | 176 | .fixup : { 177 | __fixup_start = .; 178 | *(.fixup) 179 | __fixup_end = .; 180 | } > psu_ddr_0_MEM_0 181 | 182 | .eh_frame : { 183 | *(.eh_frame) 184 | } > psu_ddr_0_MEM_0 185 | 186 | .eh_framehdr : { 187 | __eh_framehdr_start = .; 188 | *(.eh_framehdr) 189 | __eh_framehdr_end = .; 190 | } > psu_ddr_0_MEM_0 191 | 192 | .gcc_except_table : { 193 | *(.gcc_except_table) 194 | } > psu_ddr_0_MEM_0 195 | 196 | .bss (NOLOAD) : { 197 | . = ALIGN(64); 198 | _bss = .; 199 | *(.bss) 200 | *(.bss.*) 201 | *(.sbss) 202 | *(.sbss.*) 203 | *(.gnu.linkonce.b.*) 204 | *(COMMON) 205 | . = ALIGN(64); 206 | _ebss = .; 207 | end = .; 208 | } > psu_ddr_0_MEM_0 209 | 210 | /* Generate Stack and Heap definitions */ 211 | 212 | .heap (NOLOAD) : { 213 | . = ALIGN(64); 214 | _heap = .; 215 | HeapBase = .; 216 | _heap_start = .; 217 | *(.heap*) 218 | . += _HEAP_SIZE; 219 | _heap_size = _HEAP_SIZE; 220 | _heap_end = .; 221 | HeapLimit = .; 222 | } > psu_ddr_0_MEM_0 223 | 224 | .stack (NOLOAD) : { 225 | . = ALIGN(64); 226 | _stack_end_end = .; 227 | . += _STACK_SIZE; 228 | _stack_top = .; 229 | } > psu_ddr_0_MEM_0 230 | 231 | _end = .; 232 | } 233 | 234 | -------------------------------------------------------------------------------- /variants/duo/variant.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIANT_H 2 | #define VARIANT_H 3 | #include "variant_pins.h" 4 | #include "variant_soc.h" 5 | 6 | #define DEBUG_SERIAL Serial3 7 | #define DEBUG_UART_BASE DW_UART3_BASE 8 | 9 | #define WIRE_INTERFACES_COUNT 4 10 | #define OUT_PIN_NUM 41 11 | 12 | #define digitalPinToInterrupt(p) (((p) < CONFIG_GPIO_NUM * 32) ? (p) : -1) 13 | 14 | #define SERIAL_INTERFACES_COUNT 5 15 | 16 | #define Wire Wire0 17 | #endif 18 | -------------------------------------------------------------------------------- /variants/duo256/link.ld: -------------------------------------------------------------------------------- 1 | /*******************************************************************/ 2 | /* */ 3 | /* This file is automatically generated by linker script generator.*/ 4 | /* */ 5 | /* Version: */ 6 | /* */ 7 | /* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */ 8 | /* */ 9 | /* Description : Cortex-A53 Linker Script */ 10 | /* */ 11 | /*******************************************************************/ 12 | OUTPUT_ARCH( "riscv" ) 13 | OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") 14 | 15 | _STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x40000; 16 | /*_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x1000000;*/ 17 | _HEAP_SIZE = 0x80000; 18 | 19 | _EL0_STACK_SIZE = DEFINED(_EL0_STACK_SIZE) ? _EL0_STACK_SIZE : 1024; 20 | _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 2048; 21 | _EL2_STACK_SIZE = DEFINED(_EL2_STACK_SIZE) ? _EL2_STACK_SIZE : 1024; 22 | 23 | /* Define Memories in the system */ 24 | 25 | MEMORY 26 | { 27 | psu_ddr_0_MEM_0 : ORIGIN = 0x8fe00000 , LENGTH = 0x200000 28 | } 29 | 30 | /* Specify the default entry point to the program */ 31 | 32 | /*ENTRY(_vector_table)*/ 33 | ENTRY(Reset_Handler) 34 | 35 | /* Define the sections, and where they are mapped in memory */ 36 | 37 | SECTIONS 38 | { 39 | .text : { 40 | KEEP (*(.vectors)) 41 | *(.boot) 42 | *(.text) 43 | *(.text.*) 44 | *(.gnu.linkonce.t.*) 45 | *(.plt) 46 | *(.gnu_warning) 47 | *(.gcc_execpt_table) 48 | *(.glue_7) 49 | *(.glue_7t) 50 | *(.ARM.extab) 51 | *(.gnu.linkonce.armextab.*) 52 | } > psu_ddr_0_MEM_0 53 | 54 | .init (ALIGN(64)) : { 55 | KEEP (*(.init)) 56 | } > psu_ddr_0_MEM_0 57 | 58 | .fini (ALIGN(64)) : { 59 | KEEP (*(.fini)) 60 | } > psu_ddr_0_MEM_0 61 | 62 | .interp : { 63 | KEEP (*(.interp)) 64 | } > psu_ddr_0_MEM_0 65 | 66 | .note-ABI-tag : { 67 | KEEP (*(.note-ABI-tag)) 68 | } > psu_ddr_0_MEM_0 69 | 70 | .rodata : { 71 | . = ALIGN(64); 72 | __rodata_start = .; 73 | *(.rodata) 74 | *(.rodata.*) 75 | *(.srodata*) 76 | *(.gnu.linkonce.r.*) 77 | __rodata_end = .; 78 | } > psu_ddr_0_MEM_0 79 | 80 | .rodata1 : { 81 | . = ALIGN(64); 82 | __rodata1_start = .; 83 | *(.rodata1) 84 | *(.rodata1.*) 85 | __rodata1_end = .; 86 | } > psu_ddr_0_MEM_0 87 | 88 | .rodata2 : { 89 | __init_array_start = .; 90 | __ctors_start__ = .; 91 | KEEP (*(SORT(.init_array.*))) 92 | KEEP (*(.init_array)) 93 | __init_array_end = .; 94 | __ctors_end__ = .; 95 | 96 | __fini_array_start = .; 97 | __dtors_start__ = .; 98 | KEEP (*(SORT(.fini_array.*))) 99 | KEEP (*(.fini_array)) 100 | __fini_array_end = .; 101 | __dtors_end__ = .; 102 | 103 | __ctor_start__ = .; 104 | KEEP (*(SORT(.ctors.*))) 105 | KEEP (*(.ctors)) 106 | __ctor_end__ = .; 107 | KEEP (*(SORT(.dtors.*))) 108 | KEEP (*(.dtors)) 109 | __dtor_end__ = .; 110 | . = ALIGN(0x8) ; 111 | } > psu_ddr_0_MEM_0 112 | 113 | .data : { 114 | . = ALIGN(64); 115 | _data = .; 116 | *(.data) 117 | *(.data.*) 118 | *(.sdata) 119 | *(.sdata.*) 120 | *(.gnu.linkonce.d.*) 121 | *(.jcr) 122 | *(.got) 123 | *(.got.plt) 124 | _edata = .; 125 | } > psu_ddr_0_MEM_0 126 | 127 | .data1 : { 128 | . = ALIGN(64); 129 | __data1_start = .; 130 | *(.data1) 131 | *(.data1.*) 132 | __data1_end = .; 133 | } > psu_ddr_0_MEM_0 134 | 135 | .resource_table : 136 | { 137 | KEEP(*(.resource_table)); 138 | } > psu_ddr_0_MEM_0 139 | 140 | .got : { 141 | *(.got) 142 | } > psu_ddr_0_MEM_0 143 | 144 | .got1 : { 145 | *(.got1) 146 | } > psu_ddr_0_MEM_0 147 | 148 | .got2 : { 149 | *(.got2) 150 | } > psu_ddr_0_MEM_0 151 | 152 | .ctors : { 153 | . = ALIGN(64); 154 | __CTOR_LIST__ = .; 155 | ___CTORS_LIST___ = .; 156 | KEEP (*crtbegin.o(.ctors)) 157 | KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) 158 | KEEP (*(SORT(.ctors.*))) 159 | KEEP (*(.ctors)) 160 | __CTOR_END__ = .; 161 | ___CTORS_END___ = .; 162 | } > psu_ddr_0_MEM_0 163 | 164 | .dtors : { 165 | . = ALIGN(64); 166 | __DTOR_LIST__ = .; 167 | ___DTORS_LIST___ = .; 168 | KEEP (*crtbegin.o(.dtors)) 169 | KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) 170 | KEEP (*(SORT(.dtors.*))) 171 | KEEP (*(.dtors)) 172 | __DTOR_END__ = .; 173 | ___DTORS_END___ = .; 174 | } > psu_ddr_0_MEM_0 175 | 176 | .fixup : { 177 | __fixup_start = .; 178 | *(.fixup) 179 | __fixup_end = .; 180 | } > psu_ddr_0_MEM_0 181 | 182 | .eh_frame : { 183 | *(.eh_frame) 184 | } > psu_ddr_0_MEM_0 185 | 186 | .eh_framehdr : { 187 | __eh_framehdr_start = .; 188 | *(.eh_framehdr) 189 | __eh_framehdr_end = .; 190 | } > psu_ddr_0_MEM_0 191 | 192 | .gcc_except_table : { 193 | *(.gcc_except_table) 194 | } > psu_ddr_0_MEM_0 195 | 196 | .bss (NOLOAD) : { 197 | . = ALIGN(64); 198 | _bss = .; 199 | *(.bss) 200 | *(.bss.*) 201 | *(.sbss) 202 | *(.sbss.*) 203 | *(.gnu.linkonce.b.*) 204 | *(COMMON) 205 | . = ALIGN(64); 206 | _ebss = .; 207 | end = .; 208 | } > psu_ddr_0_MEM_0 209 | 210 | /* Generate Stack and Heap definitions */ 211 | 212 | .heap (NOLOAD) : { 213 | . = ALIGN(64); 214 | _heap = .; 215 | HeapBase = .; 216 | _heap_start = .; 217 | *(.heap*) 218 | . += _HEAP_SIZE; 219 | _heap_size = _HEAP_SIZE; 220 | _heap_end = .; 221 | HeapLimit = .; 222 | } > psu_ddr_0_MEM_0 223 | 224 | .stack (NOLOAD) : { 225 | . = ALIGN(64); 226 | _stack_end_end = .; 227 | . += _STACK_SIZE; 228 | _stack_top = .; 229 | } > psu_ddr_0_MEM_0 230 | 231 | _end = .; 232 | } 233 | 234 | -------------------------------------------------------------------------------- /variants/duo256/variant.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIANT_H 2 | #define VARIANT_H 3 | #include "variant_pins.h" 4 | #include "../duo/variant_soc.h" 5 | 6 | #define DEBUG_SERIAL Serial3 7 | #define DEBUG_UART_BASE DW_UART3_BASE 8 | 9 | #define WIRE_INTERFACES_COUNT 4 10 | #define OUT_PIN_NUM 41 11 | 12 | #define digitalPinToInterrupt(p) (((p) < CONFIG_GPIO_NUM * 32) ? (p) : -1) 13 | 14 | #define SERIAL_INTERFACES_COUNT 4 15 | 16 | #define Wire Wire1 17 | #endif 18 | --------------------------------------------------------------------------------